From 0296bb563fe36bfce27090ece90ad5b64e400df3 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Thu, 21 Nov 2024 21:40:47 +0000 Subject: [PATCH 01/11] Allow classes whose object representation is an integer type to be used with integer tyye builtins. --- toolchain/check/eval.cpp | 10 ++++--- toolchain/lower/constant.cpp | 3 +- toolchain/sem_ir/BUILD | 1 + toolchain/sem_ir/file.h | 26 +--------------- toolchain/sem_ir/type.cpp | 58 ++++++++++++++++++++++++++++++++++++ toolchain/sem_ir/type.h | 48 ++++++++++++++++------------- 6 files changed, 95 insertions(+), 51 deletions(-) create mode 100644 toolchain/sem_ir/type.cpp diff --git a/toolchain/check/eval.cpp b/toolchain/check/eval.cpp index 280462d6a22b2..6ae645d8cd44d 100644 --- a/toolchain/check/eval.cpp +++ b/toolchain/check/eval.cpp @@ -675,7 +675,7 @@ static auto PerformCheckedIntConvert(Context& context, SemIRLoc loc, auto arg_val = context.ints().Get(arg.int_id); auto [is_signed, bit_width_id] = - context.sem_ir().GetIntTypeInfo(dest_type_id); + context.sem_ir().types().GetIntTypeInfo(dest_type_id); auto width = bit_width_id.is_valid() ? context.ints().Get(bit_width_id).getZExtValue() : arg_val.getBitWidth(); @@ -717,7 +717,8 @@ static auto PerformBuiltinUnaryIntOp(Context& context, SemIRLoc loc, SemIR::InstId arg_id) -> SemIR::ConstantId { auto op = context.insts().GetAs(arg_id); - auto [is_signed, bit_width_id] = context.sem_ir().GetIntTypeInfo(op.type_id); + auto [is_signed, bit_width_id] = + context.sem_ir().types().GetIntTypeInfo(op.type_id); CARBON_CHECK(bit_width_id != IntId::Invalid, "Cannot evaluate a generic bit width integer: {0}", op); llvm::APInt op_val = context.ints().GetAtWidth(op.int_id, bit_width_id); @@ -770,7 +771,7 @@ static auto PerformBuiltinBinaryIntOp(Context& context, SemIRLoc loc, } auto [lhs_is_signed, lhs_bit_width_id] = - context.sem_ir().GetIntTypeInfo(lhs.type_id); + context.sem_ir().types().GetIntTypeInfo(lhs.type_id); llvm::APInt lhs_val = context.ints().GetAtWidth(lhs.int_id, lhs_bit_width_id); llvm::APInt result_val; @@ -915,7 +916,8 @@ static auto PerformBuiltinIntComparison(Context& context, CARBON_CHECK(lhs.type_id == rhs.type_id, "Builtin comparison with mismatched types!"); - auto [is_signed, bit_width_id] = context.sem_ir().GetIntTypeInfo(lhs.type_id); + auto [is_signed, bit_width_id] = + context.sem_ir().types().GetIntTypeInfo(lhs.type_id); CARBON_CHECK(bit_width_id != IntId::Invalid, "Cannot evaluate a generic bit width integer: {0}", lhs); llvm::APInt lhs_val = context.ints().GetAtWidth(lhs.int_id, bit_width_id); diff --git a/toolchain/lower/constant.cpp b/toolchain/lower/constant.cpp index f7dc290c4d00c..38e58faab7de2 100644 --- a/toolchain/lower/constant.cpp +++ b/toolchain/lower/constant.cpp @@ -219,7 +219,8 @@ static auto EmitAsConstant(ConstantContext& context, SemIR::IntValue inst) auto val = context.sem_ir().ints().Get(inst.int_id); int bit_width = int_type->getBitWidth(); - bool is_signed = context.sem_ir().GetIntTypeInfo(inst.type_id).is_signed; + bool is_signed = + context.sem_ir().types().GetIntTypeInfo(inst.type_id).is_signed; return llvm::ConstantInt::get(type, is_signed ? val.sextOrTrunc(bit_width) : val.zextOrTrunc(bit_width)); } diff --git a/toolchain/sem_ir/BUILD b/toolchain/sem_ir/BUILD index 3422f088997cb..48764a138de24 100644 --- a/toolchain/sem_ir/BUILD +++ b/toolchain/sem_ir/BUILD @@ -74,6 +74,7 @@ cc_library( "generic.cpp", "impl.cpp", "name.cpp", + "type.cpp", "type_info.cpp", ], hdrs = [ diff --git a/toolchain/sem_ir/file.h b/toolchain/sem_ir/file.h index 3324dd32be28d..4f289d0c03395 100644 --- a/toolchain/sem_ir/file.h +++ b/toolchain/sem_ir/file.h @@ -36,12 +36,6 @@ namespace Carbon::SemIR { // Provides semantic analysis on a Parse::Tree. class File : public Printable { public: - // Used to return information about an integer type in `GetIntTypeInfo`. - struct IntTypeInfo { - bool is_signed; - IntId bit_width; - }; - // Starts a new file for Check::CheckParseTree. explicit File(CheckIRId check_ir_id, IdentifierId package_id, LibraryNameId library_id, SharedValueStores& value_stores, @@ -78,24 +72,6 @@ class File : public Printable { return types().GetAs(pointer_id).pointee_id; } - // Returns integer type information from a type ID. Abstracts away the - // difference between an `IntType` instruction defined type and a builtin - // instruction defined type. Uses IntId::Invalid for types that have an - // invalid width. - // - // TODO: Move this to TypeStore. - auto GetIntTypeInfo(TypeId int_type_id) const -> IntTypeInfo { - auto inst_id = types().GetInstId(int_type_id); - if (inst_id == InstId::BuiltinIntLiteralType) { - return {.is_signed = true, .bit_width = IntId::Invalid}; - } - auto int_type = insts().GetAs(inst_id); - auto bit_width_inst = insts().TryGetAs(int_type.bit_width_id); - return { - .is_signed = int_type.int_kind.is_signed(), - .bit_width = bit_width_inst ? bit_width_inst->int_id : IntId::Invalid}; - } - auto check_ir_id() const -> CheckIRId { return check_ir_id_; } auto package_id() const -> IdentifierId { return package_id_; } auto library_id() const -> SemIR::LibraryNameId { return library_id_; } @@ -292,7 +268,7 @@ class File : public Printable { StructTypeFieldsStore struct_type_fields_ = StructTypeFieldsStore(allocator_); // Descriptions of types used in this file. - TypeStore types_ = TypeStore(&insts_, &constant_values_); + TypeStore types_ = TypeStore(this); }; // The expression category of a sem_ir instruction. See /docs/design/values.md diff --git a/toolchain/sem_ir/type.cpp b/toolchain/sem_ir/type.cpp new file mode 100644 index 0000000000000..56317137c5b4c --- /dev/null +++ b/toolchain/sem_ir/type.cpp @@ -0,0 +1,58 @@ +// 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 "toolchain/sem_ir/type.h" + +#include "toolchain/sem_ir/file.h" + +namespace Carbon::SemIR { + +auto TypeStore::GetInstId(TypeId type_id) const -> InstId { + return file_->constant_values().GetInstId(GetConstantId(type_id)); +} + +auto TypeStore::GetAsInst(TypeId type_id) const -> Inst { + return file_->insts().Get(GetInstId(type_id)); +} + +auto TypeStore::GetObjectRepr(TypeId type_id) const -> TypeId { + auto class_type = TryGetAs(type_id); + if (!class_type) { + return type_id; + } + const auto& class_info = file_->classes().Get(class_type->class_id); + if (!class_info.is_defined()) { + return TypeId::Invalid; + } + return class_info.GetObjectRepr(*file_, class_type->specific_id); +} + +auto TypeStore::IsSignedInt(TypeId int_type_id) const -> bool { + auto object_repr_id = GetObjectRepr(int_type_id); + if (!object_repr_id.is_valid()) { + return false; + } + auto inst_id = GetInstId(int_type_id); + if (inst_id == InstId::BuiltinIntLiteralType) { + return true; + } + auto int_type = file_->insts().TryGetAs(inst_id); + return int_type && int_type->int_kind.is_signed(); +} + +auto TypeStore::GetIntTypeInfo(TypeId int_type_id) const -> IntTypeInfo { + auto object_repr_id = GetObjectRepr(int_type_id); + auto inst_id = GetInstId(object_repr_id); + if (inst_id == InstId::BuiltinIntLiteralType) { + return {.is_signed = true, .bit_width = IntId::Invalid}; + } + auto int_type = file_->insts().GetAs(inst_id); + auto bit_width_inst = + file_->insts().TryGetAs(int_type.bit_width_id); + return { + .is_signed = int_type.int_kind.is_signed(), + .bit_width = bit_width_inst ? bit_width_inst->int_id : IntId::Invalid}; +} + +} // namespace Carbon::SemIR diff --git a/toolchain/sem_ir/type.h b/toolchain/sem_ir/type.h index 1599c175d5e2b..72831833351a4 100644 --- a/toolchain/sem_ir/type.h +++ b/toolchain/sem_ir/type.h @@ -16,8 +16,13 @@ namespace Carbon::SemIR { // Provides a ValueStore wrapper with an API specific to types. class TypeStore : public Yaml::Printable { public: - explicit TypeStore(InstStore* insts, ConstantValueStore* constants) - : insts_(insts), constants_(constants) {} + // Used to return information about an integer type in `GetIntTypeInfo`. + struct IntTypeInfo { + bool is_signed; + IntId bit_width; + }; + + explicit TypeStore(File* file) : file_(file) {} // Returns the ID of the constant used to define the specified type. auto GetConstantId(TypeId type_id) const -> ConstantId { @@ -29,14 +34,10 @@ class TypeStore : public Yaml::Printable { } // Returns the ID of the instruction used to define the specified type. - auto GetInstId(TypeId type_id) const -> InstId { - return constants_->GetInstId(GetConstantId(type_id)); - } + auto GetInstId(TypeId type_id) const -> InstId; // Returns the instruction used to define the specified type. - auto GetAsInst(TypeId type_id) const -> Inst { - return insts_->Get(GetInstId(type_id)); - } + auto GetAsInst(TypeId type_id) const -> Inst; // Returns whether the specified kind of instruction was used to define the // type. @@ -49,8 +50,7 @@ class TypeStore : public Yaml::Printable { // to be a particular kind of instruction. template auto GetAs(TypeId type_id) const -> InstT { - auto inst_id = constants_->GetInstId(GetConstantId(type_id)); - return insts_->GetAs(inst_id); + return GetAsInst(type_id).As(); } // Returns the instruction used to define the specified type, if it is of a @@ -87,21 +87,28 @@ class TypeStore : public Yaml::Printable { CARBON_CHECK(IsComplete(type_id)); } + // Get the object representation associated with a type. For a non-class type, + // this is the type itself. An invalid TypeId is returned if the object + // representation cannot be determined because the type is not complete. + auto GetObjectRepr(TypeId type_id) const -> TypeId; + // Determines whether the given type is known to be complete. This does not // determine whether the type could be completed, only whether it has been. auto IsComplete(TypeId type_id) const -> bool { return complete_type_info_.Contains(type_id); } - // Determines whether the given type is a signed integer type. - auto IsSignedInt(TypeId int_type_id) const -> bool { - auto inst_id = GetInstId(int_type_id); - if (inst_id == InstId::BuiltinIntLiteralType) { - return true; - } - auto int_type = insts_->TryGetAs(inst_id); - return int_type && int_type->int_kind.is_signed(); - } + // Determines whether the given type is a signed integer type. This includes + // the case where the type is `Core.IntLiteral` or a class type whose object + // representation is a signed integer type. + auto IsSignedInt(TypeId int_type_id) const -> bool; + + // Returns integer type information from a type ID that is known to represent + // an integer type. Abstracts away the difference between an `IntType` + // instruction defined type, a builtin instruction defined type, and a class + // adapting such a type. Uses IntId::Invalid for types that have a + // non-constant width and for IntLiteral. + auto GetIntTypeInfo(TypeId int_type_id) const -> IntTypeInfo; // Returns a list of types that were completed in this file, in the order in // which they were completed. Earlier types in this list cannot contain @@ -128,8 +135,7 @@ class TypeStore : public Yaml::Printable { } private: - InstStore* insts_; - ConstantValueStore* constants_; + File* file_; Map complete_type_info_; llvm::SmallVector complete_types_; }; From cbe5eb7ed9471f966fc76a3dd4a127546ba08fa6 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Thu, 21 Nov 2024 21:44:52 +0000 Subject: [PATCH 02/11] Support generic adapters, bases and import better. --- toolchain/check/context.cpp | 34 ++--- toolchain/check/context.h | 3 - toolchain/check/convert.cpp | 20 +-- toolchain/check/handle_class.cpp | 49 +++---- toolchain/check/import_ref.cpp | 10 +- toolchain/check/member_access.cpp | 18 ++- toolchain/check/pointer_dereference.cpp | 4 +- .../testdata/as/adapter_conversion.carbon | 126 +++++++++--------- toolchain/check/testdata/class/adapt.carbon | 12 +- toolchain/check/testdata/class/base.carbon | 2 +- .../check/testdata/class/base_field.carbon | 2 +- .../class/base_function_unqualified.carbon | 2 +- .../check/testdata/class/base_method.carbon | 2 +- .../class/base_method_qualified.carbon | 2 +- .../testdata/class/base_method_shadow.carbon | 6 +- .../testdata/class/compound_field.carbon | 2 +- .../testdata/class/derived_to_base.carbon | 4 +- .../check/testdata/class/extend_adapt.carbon | 21 ++- .../check/testdata/class/fail_abstract.carbon | 6 +- .../testdata/class/fail_adapt_bad_decl.carbon | 4 +- .../class/fail_adapt_modifiers.carbon | 21 ++- .../class/fail_adapt_with_base.carbon | 2 +- .../class/fail_adapt_with_subobjects.carbon | 12 +- .../testdata/class/fail_base_bad_type.carbon | 2 +- .../class/fail_base_method_define.carbon | 2 +- .../testdata/class/fail_base_modifiers.carbon | 8 +- .../testdata/class/fail_base_no_extend.carbon | 2 +- .../testdata/class/fail_base_repeated.carbon | 4 +- .../testdata/class/fail_base_unbound.carbon | 2 +- .../class/fail_derived_to_base.carbon | 2 +- .../testdata/class/fail_extend_cycle.carbon | 4 +- .../class/generic/base_is_generic.carbon | 30 ++--- .../check/testdata/class/generic/init.carbon | 2 +- .../check/testdata/class/import_base.carbon | 16 +-- .../testdata/class/inheritance_access.carbon | 18 +-- .../check/testdata/class/init_adapt.carbon | 114 ++++++++-------- .../testdata/class/self_conversion.carbon | 2 +- .../testdata/class/virtual_modifiers.carbon | 2 +- .../testdata/impl/multiple_extend.carbon | 6 +- toolchain/lower/handle_aggregates.cpp | 5 +- toolchain/sem_ir/class.cpp | 27 ++++ toolchain/sem_ir/class.h | 8 ++ toolchain/sem_ir/type.cpp | 8 ++ toolchain/sem_ir/type.h | 3 + toolchain/sem_ir/typed_insts.h | 4 +- 45 files changed, 331 insertions(+), 304 deletions(-) diff --git a/toolchain/check/context.cpp b/toolchain/check/context.cpp index 1ce4ffe4df8bc..914e3b7f9da38 100644 --- a/toolchain/check/context.cpp +++ b/toolchain/check/context.cpp @@ -381,18 +381,19 @@ static auto DiagnoseInvalidQualifiedNameAccess(Context& context, SemIRLoc loc, } // TODO: Support scoped entities other than just classes. - auto class_info = context.classes().Get(class_type->class_id); + const auto& class_info = context.classes().Get(class_type->class_id); auto parent_type_id = class_info.self_type_id; if (access_kind == SemIR::AccessKind::Private && is_parent_access) { - if (auto base_decl = context.insts().TryGetAsIfValid( - class_info.base_id)) { - parent_type_id = base_decl->base_type_id; - } else if (auto adapt_decl = - context.insts().TryGetAsIfValid( - class_info.adapt_id)) { - parent_type_id = adapt_decl->adapted_type_id; + if (auto base_type_id = + class_info.GetBaseType(context.sem_ir(), class_type->specific_id); + base_type_id.is_valid()) { + parent_type_id = base_type_id; + } else if (auto adapted_type_id = class_info.GetAdaptedType( + context.sem_ir(), class_type->specific_id); + adapted_type_id.is_valid()) { + parent_type_id = adapted_type_id; } else { CARBON_FATAL("Expected parent for parent access"); } @@ -1116,12 +1117,10 @@ class TypeCompleter { auto& class_info = context_.classes().Get(inst.class_id); // The value representation of an adapter is the value representation of // its adapted type. - if (class_info.adapt_id.is_valid()) { - return GetNestedValueRepr(SemIR::GetTypeInSpecific( - context_.sem_ir(), inst.specific_id, - context_.insts() - .GetAs(class_info.adapt_id) - .adapted_type_id)); + if (auto adapted_type_id = + class_info.GetAdaptedType(context_.sem_ir(), inst.specific_id); + adapted_type_id.is_valid()) { + return GetNestedValueRepr(adapted_type_id); } // Otherwise, the value representation for a class is a pointer to the // object representation. @@ -1388,13 +1387,6 @@ auto Context::GetUnboundElementType(SemIR::TypeId class_type_id, element_type_id); } -auto Context::GetUnqualifiedType(SemIR::TypeId type_id) -> SemIR::TypeId { - if (auto const_type = types().TryGetAs(type_id)) { - return const_type->inner_id; - } - return type_id; -} - auto Context::PrintForStackDump(llvm::raw_ostream& output) const -> void { output << "Check::Context\n"; diff --git a/toolchain/check/context.h b/toolchain/check/context.h index a66d527e03a7a..69221f2f44478 100644 --- a/toolchain/check/context.h +++ b/toolchain/check/context.h @@ -426,9 +426,6 @@ class Context { auto GetUnboundElementType(SemIR::TypeId class_type_id, SemIR::TypeId element_type_id) -> SemIR::TypeId; - // Removes any top-level `const` qualifiers from a type. - auto GetUnqualifiedType(SemIR::TypeId type_id) -> SemIR::TypeId; - // Adds an exported name. auto AddExport(SemIR::InstId inst_id) -> void { exports_.push_back(inst_id); } diff --git a/toolchain/check/convert.cpp b/toolchain/check/convert.cpp index 7b245836695cd..25748bc31a1d9 100644 --- a/toolchain/check/convert.cpp +++ b/toolchain/check/convert.cpp @@ -604,15 +604,12 @@ static auto ComputeInheritancePath(Context& context, SemIR::TypeId derived_id, break; } auto& derived_class = context.classes().Get(derived_class_type->class_id); - if (!derived_class.base_id.is_valid()) { + auto base_type_id = derived_class.GetBaseType( + context.sem_ir(), derived_class_type->specific_id); + if (!base_type_id.is_valid()) { result = std::nullopt; break; } - auto base_decl = - context.insts().GetAs(derived_class.base_id); - auto base_type_id = SemIR::GetTypeInSpecific( - context.sem_ir(), derived_class_type->specific_id, - base_decl.base_type_id); result->push_back({derived_class.base_id, base_type_id}); derived_id = base_type_id; } @@ -709,12 +706,15 @@ static auto GetCompatibleBaseType(Context& context, SemIR::TypeId type_id) -> SemIR::TypeId { // If the type is an adapter, its object representation type is its compatible // non-adapter type. - if (auto class_type = context.types().TryGetAs(type_id)) { + while (auto class_type = + context.types().TryGetAs(type_id)) { auto& class_info = context.classes().Get(class_type->class_id); - if (class_info.adapt_id.is_valid()) { - return class_info.GetObjectRepr(context.sem_ir(), - class_type->specific_id); + auto adapted_type_id = + class_info.GetAdaptedType(context.sem_ir(), class_type->specific_id); + if (!adapted_type_id.is_valid()) { + break; } + type_id = adapted_type_id; } // Otherwise, the type itself is a non-adapter type. diff --git a/toolchain/check/handle_class.cpp b/toolchain/check/handle_class.cpp index dea13ca8d4c4a..eadf80aa6ad80 100644 --- a/toolchain/check/handle_class.cpp +++ b/toolchain/check/handle_class.cpp @@ -6,6 +6,7 @@ #include "toolchain/check/context.h" #include "toolchain/check/convert.h" #include "toolchain/check/decl_name_stack.h" +#include "toolchain/check/diagnostic_helpers.h" #include "toolchain/check/eval.h" #include "toolchain/check/generic.h" #include "toolchain/check/handle.h" @@ -387,21 +388,24 @@ auto HandleParseNode(Context& context, Parse::AdaptDeclId node_id) -> bool { [&] { CARBON_DIAGNOSTIC(IncompleteTypeInAdaptDecl, Error, "adapted type {0} is an incomplete type", - SemIR::TypeId); + InstIdAsType); return context.emitter().Build(node_id, IncompleteTypeInAdaptDecl, - adapted_type_id); + adapted_inst_id); }, [&] { CARBON_DIAGNOSTIC(AbstractTypeInAdaptDecl, Error, "adapted type {0} is an abstract type", - SemIR::TypeId); + InstIdAsType); return context.emitter().Build(node_id, AbstractTypeInAdaptDecl, - adapted_type_id); + adapted_inst_id); }); + if (adapted_type_id == SemIR::TypeId::Error) { + adapted_inst_id = SemIR::InstId::BuiltinErrorInst; + } // Build a SemIR representation for the declaration. class_info.adapt_id = context.AddInst( - node_id, {.adapted_type_id = adapted_type_id}); + node_id, {.adapted_type_inst_id = adapted_inst_id}); // Extend the class scope with the adapted type's scope if requested. if (introducer.modifier_set.HasAnyOf(KeywordModifierSet::Extend)) { @@ -432,9 +436,10 @@ struct BaseInfo { SemIR::NameScopeId scope_id; SemIR::InstId inst_id; }; -constexpr BaseInfo BaseInfo::Error = {.type_id = SemIR::TypeId::Error, - .scope_id = SemIR::NameScopeId::Invalid, - .inst_id = SemIR::InstId::Invalid}; +constexpr BaseInfo BaseInfo::Error = { + .type_id = SemIR::TypeId::Error, + .scope_id = SemIR::NameScopeId::Invalid, + .inst_id = SemIR::InstId::BuiltinErrorInst}; } // namespace // Diagnoses an attempt to derive from a final type. @@ -529,7 +534,7 @@ auto HandleParseNode(Context& context, Parse::BaseDeclId node_id) -> bool { context.GetUnboundElementType(class_info.self_type_id, base_info.type_id); class_info.base_id = context.AddInst( node_id, {.type_id = field_type_id, - .base_type_id = base_info.type_id, + .base_type_inst_id = base_info.inst_id, .index = SemIR::ElementIndex( context.struct_type_fields_stack().PeekArray().size())}); @@ -616,26 +621,15 @@ static auto CheckCompleteAdapterClassType(Context& context, } // The object representation of the adapter is the object representation - // of the adapted type. This is the adapted type itself unless it's a class - // type. - // - // TODO: The object representation of `const T` should also be the object - // representation of `T`. - auto adapted_type_id = context.insts() - .GetAs(class_info.adapt_id) - .adapted_type_id; - if (auto adapted_class = - context.types().TryGetAs(adapted_type_id)) { - auto& adapted_class_info = context.classes().Get(adapted_class->class_id); - if (adapted_class_info.adapt_id.is_valid()) { - return adapted_class_info.complete_type_witness_id; - } - } + // of the adapted type. + auto adapted_type_id = + class_info.GetAdaptedType(context.sem_ir(), SemIR::SpecificId::Invalid); + auto object_repr_id = context.types().GetObjectRepr(adapted_type_id); return context.AddInst( node_id, {.type_id = context.GetBuiltinType(SemIR::BuiltinInstKind::WitnessType), - .object_repr_id = adapted_type_id}); + .object_repr_id = object_repr_id}); } // Checks that the specified finished class definition is valid and builds and @@ -653,10 +647,11 @@ static auto CheckCompleteClassType(Context& context, Parse::NodeId node_id, bool defining_vtable_ptr = class_info.is_dynamic; if (class_info.base_id.is_valid()) { - auto base_info = context.insts().GetAs(class_info.base_id); + auto base_type_id = + class_info.GetBaseType(context.sem_ir(), SemIR::SpecificId::Invalid); // TODO: If the base class is template dependent, we will need to decide // whether to add a vptr as part of instantiation. - if (auto* base_class_info = TryGetAsClass(context, base_info.base_type_id); + if (auto* base_class_info = TryGetAsClass(context, base_type_id); base_class_info && base_class_info->is_dynamic) { defining_vtable_ptr = false; } diff --git a/toolchain/check/import_ref.cpp b/toolchain/check/import_ref.cpp index c62b9d862f66c..9356a2f591f14 100644 --- a/toolchain/check/import_ref.cpp +++ b/toolchain/check/import_ref.cpp @@ -1359,19 +1359,23 @@ class ImportRefResolver { auto TryResolveTypedInst(SemIR::BaseDecl inst, SemIR::InstId import_inst_id) -> ResolveResult { auto type_const_id = GetLocalConstantId(inst.type_id); - auto base_type_const_id = GetLocalConstantId(inst.base_type_id); + auto base_type_const_id = GetLocalConstantId( + import_ir_.constant_values().Get(inst.base_type_inst_id)); if (HasNewWork()) { return Retry(); } + auto base_type_inst_id = AddLoadedImportRef( + context_, {.ir_id = import_ir_id_, .inst_id = inst.base_type_inst_id}, + SemIR::TypeId::TypeType, base_type_const_id); + // Import the instruction in order to update contained base_type_id and // track the import location. auto inst_id = context_.AddInstInNoBlock( context_.MakeImportedLocAndInst( AddImportIRInst(import_inst_id), {.type_id = context_.GetTypeIdForTypeConstant(type_const_id), - .base_type_id = - context_.GetTypeIdForTypeConstant(base_type_const_id), + .base_type_inst_id = base_type_inst_id, .index = inst.index})); return ResolveAsConstant(context_.constant_values().Get(inst_id)); } diff --git a/toolchain/check/member_access.cpp b/toolchain/check/member_access.cpp index cce4dd0772657..319ffdf821d23 100644 --- a/toolchain/check/member_access.cpp +++ b/toolchain/check/member_access.cpp @@ -81,15 +81,19 @@ static auto GetHighestAllowedAccess(Context& context, SemIR::LocId loc_id, // If the `type_id` of `Self` does not match with the one we're currently // accessing, try checking if this class is of the parent type of `Self`. - if (auto base_decl = context.insts().TryGetAsIfValid( - self_class_info.base_id)) { - if (base_decl->base_type_id == class_info.self_type_id) { + if (auto base_type_id = self_class_info.GetBaseType( + context.sem_ir(), self_class_type->specific_id); + base_type_id.is_valid()) { + if (context.types().GetConstantId(base_type_id) == name_scope_const_id) { return SemIR::AccessKind::Protected; } - } else if (auto adapt_decl = - context.insts().TryGetAsIfValid( - self_class_info.adapt_id)) { - if (adapt_decl->adapted_type_id == class_info.self_type_id) { + // TODO: Also check whether this base class has a base class of its own. + } else if (auto adapt_type_id = self_class_info.GetAdaptedType( + context.sem_ir(), self_class_type->specific_id); + adapt_type_id.is_valid()) { + if (context.types().GetConstantId(adapt_type_id) == name_scope_const_id) { + // TODO: Should we be allowed to access protected fields of a type we + // are adapting? The design doesn't allow this. return SemIR::AccessKind::Protected; } } diff --git a/toolchain/check/pointer_dereference.cpp b/toolchain/check/pointer_dereference.cpp index f1abf5370fa8e..7026f2d4a8a7c 100644 --- a/toolchain/check/pointer_dereference.cpp +++ b/toolchain/check/pointer_dereference.cpp @@ -23,8 +23,8 @@ auto PerformPointerDereference( // // to convert to a pointer value. base_id = ConvertToValueExpr(context, base_id); - auto type_id = - context.GetUnqualifiedType(context.insts().Get(base_id).type_id()); + auto type_id = context.types().GetUnqualifiedType( + context.insts().Get(base_id).type_id()); auto result_type_id = SemIR::TypeId::Error; if (auto pointer_type = context.types().TryGetAs(type_id)) { diff --git a/toolchain/check/testdata/as/adapter_conversion.carbon b/toolchain/check/testdata/as/adapter_conversion.carbon index 7fc8b4caacbd8..28529f89374f6 100644 --- a/toolchain/check/testdata/as/adapter_conversion.carbon +++ b/toolchain/check/testdata/as/adapter_conversion.carbon @@ -133,8 +133,7 @@ var b: B = {.x = 1} as B; // CHECK:STDOUT: %.34: %i32 = int_value 2 [template] // CHECK:STDOUT: %struct: %A = struct_value (%.31, %.34) [template] // CHECK:STDOUT: %B: type = class_type @B [template] -// CHECK:STDOUT: %.35: = complete_type_witness %A [template] -// CHECK:STDOUT: %.36: type = ptr_type %B [template] +// CHECK:STDOUT: %.35: type = ptr_type %B [template] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -166,7 +165,7 @@ var b: B = {.x = 1} as B; // CHECK:STDOUT: %A.ref.loc18: type = name_ref A, %A.decl [template = constants.%A] // CHECK:STDOUT: %B.ref.loc21: type = name_ref B, %B.decl [template = constants.%B] // CHECK:STDOUT: %B.ref.loc22: type = name_ref B, %B.decl [template = constants.%B] -// CHECK:STDOUT: %.loc22: type = ptr_type %B [template = constants.%.36] +// CHECK:STDOUT: %.loc22: type = ptr_type %B [template = constants.%.35] // CHECK:STDOUT: %B.ref.loc24: type = name_ref B, %B.decl [template = constants.%B] // CHECK:STDOUT: %b_factory.var: ref %B = var b_factory // CHECK:STDOUT: %b_factory: ref %B = bind_name b_factory, %b_factory.var @@ -202,8 +201,8 @@ var b: B = {.x = 1} as B; // CHECK:STDOUT: // CHECK:STDOUT: class @B { // CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [template = constants.%A] -// CHECK:STDOUT: adapt_decl %A -// CHECK:STDOUT: %.loc15: = complete_type_witness %A [template = constants.%.35] +// CHECK:STDOUT: adapt_decl %A.ref +// CHECK:STDOUT: %.loc15: = complete_type_witness %.3 [template = constants.%.4] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%B @@ -267,8 +266,8 @@ var b: B = {.x = 1} as B; // CHECK:STDOUT: %B.ref.loc22: type = name_ref B, file.%B.decl [template = constants.%B] // CHECK:STDOUT: %.loc22_25.1: ref %B = as_compatible %a_ref.ref.loc22 // CHECK:STDOUT: %.loc22_25.2: ref %B = converted %a_ref.ref.loc22, %.loc22_25.1 -// CHECK:STDOUT: %.loc22_17: %.36 = addr_of %.loc22_25.2 -// CHECK:STDOUT: %b_ptr: %.36 = bind_name b_ptr, %.loc22_17 +// CHECK:STDOUT: %.loc22_17: %.35 = addr_of %.loc22_25.2 +// CHECK:STDOUT: %b_ptr: %.35 = bind_name b_ptr, %.loc22_17 // CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [template = constants.%A] // CHECK:STDOUT: %Make.ref: %Make.type = name_ref Make, @A.%Make.decl [template = constants.%Make] // CHECK:STDOUT: %.loc24_5: ref %B = splice_block file.%b_factory.var {} @@ -329,7 +328,7 @@ var b: B = {.x = 1} as B; // CHECK:STDOUT: %int.make_type_signed: init type = call constants.%Int(%.loc5_9) [template = constants.%i32] // CHECK:STDOUT: %.loc5_12.1: type = value_of_initializer %int.make_type_signed [template = constants.%i32] // CHECK:STDOUT: %.loc5_12.2: type = converted %int.make_type_signed, %.loc5_12.1 [template = constants.%i32] -// CHECK:STDOUT: adapt_decl %i32 +// CHECK:STDOUT: adapt_decl %.loc5_12.2 // CHECK:STDOUT: %.loc6: = complete_type_witness %i32 [template = constants.%.2] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -403,7 +402,7 @@ var b: B = {.x = 1} as B; // CHECK:STDOUT: class @A { // CHECK:STDOUT: %.loc4_18: %.1 = struct_literal () // CHECK:STDOUT: %.loc4_19: type = converted %.loc4_18, constants.%.1 [template = constants.%.1] -// CHECK:STDOUT: adapt_decl %.1 +// CHECK:STDOUT: adapt_decl %.loc4_19 // CHECK:STDOUT: %.loc4_21: = complete_type_witness %.1 [template = constants.%.2] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -412,7 +411,8 @@ var b: B = {.x = 1} as B; // CHECK:STDOUT: // CHECK:STDOUT: class @B { // CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [template = constants.%A] -// CHECK:STDOUT: adapt_decl %A +// CHECK:STDOUT: adapt_decl %A.ref +// CHECK:STDOUT: %.loc5: = complete_type_witness %.1 [template = constants.%.2] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%B @@ -420,7 +420,8 @@ var b: B = {.x = 1} as B; // CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B] -// CHECK:STDOUT: adapt_decl %B +// CHECK:STDOUT: adapt_decl %B.ref +// CHECK:STDOUT: %.loc6: = complete_type_witness %.1 [template = constants.%.2] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%C @@ -428,7 +429,8 @@ var b: B = {.x = 1} as B; // CHECK:STDOUT: // CHECK:STDOUT: class @D { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [template = constants.%C] -// CHECK:STDOUT: adapt_decl %C +// CHECK:STDOUT: adapt_decl %C.ref +// CHECK:STDOUT: %.loc7: = complete_type_witness %.1 [template = constants.%.2] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%D @@ -457,21 +459,20 @@ var b: B = {.x = 1} as B; // CHECK:STDOUT: %.3: type = struct_type {.x: %i32, .y: %i32} [template] // CHECK:STDOUT: %.4: = complete_type_witness %.3 [template] // CHECK:STDOUT: %B: type = class_type @B [template] -// CHECK:STDOUT: %.6: = complete_type_witness %A [template] -// CHECK:STDOUT: %.7: Core.IntLiteral = int_value 1 [template] -// CHECK:STDOUT: %.8: Core.IntLiteral = int_value 2 [template] -// CHECK:STDOUT: %.9: type = struct_type {.x: Core.IntLiteral, .y: Core.IntLiteral} [template] +// CHECK:STDOUT: %.6: Core.IntLiteral = int_value 1 [template] +// CHECK:STDOUT: %.7: Core.IntLiteral = int_value 2 [template] +// CHECK:STDOUT: %.8: type = struct_type {.x: Core.IntLiteral, .y: Core.IntLiteral} [template] // CHECK:STDOUT: %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(%i32) [template] // CHECK:STDOUT: %Convert.type.14: type = fn_type @Convert.2, @impl.1(%.1) [template] // CHECK:STDOUT: %Convert.14: %Convert.type.14 = struct_value () [template] -// CHECK:STDOUT: %.29: = interface_witness (%Convert.14) [template] -// CHECK:STDOUT: %.30: = bound_method %.7, %Convert.14 [template] -// CHECK:STDOUT: %.31: = specific_function %.30, @Convert.2(%.1) [template] -// CHECK:STDOUT: %.32: %i32 = int_value 1 [template] -// CHECK:STDOUT: %.33: = bound_method %.8, %Convert.14 [template] -// CHECK:STDOUT: %.34: = specific_function %.33, @Convert.2(%.1) [template] -// CHECK:STDOUT: %.35: %i32 = int_value 2 [template] -// CHECK:STDOUT: %struct: %A = struct_value (%.32, %.35) [template] +// CHECK:STDOUT: %.28: = interface_witness (%Convert.14) [template] +// CHECK:STDOUT: %.29: = bound_method %.6, %Convert.14 [template] +// CHECK:STDOUT: %.30: = specific_function %.29, @Convert.2(%.1) [template] +// CHECK:STDOUT: %.31: %i32 = int_value 1 [template] +// CHECK:STDOUT: %.32: = bound_method %.7, %Convert.14 [template] +// CHECK:STDOUT: %.33: = specific_function %.32, @Convert.2(%.1) [template] +// CHECK:STDOUT: %.34: %i32 = int_value 2 [template] +// CHECK:STDOUT: %struct: %A = struct_value (%.31, %.34) [template] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -521,8 +522,8 @@ var b: B = {.x = 1} as B; // CHECK:STDOUT: // CHECK:STDOUT: class @B { // CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [template = constants.%A] -// CHECK:STDOUT: adapt_decl %A -// CHECK:STDOUT: %.loc11: = complete_type_witness %A [template = constants.%.6] +// CHECK:STDOUT: adapt_decl %A.ref +// CHECK:STDOUT: %.loc11: = complete_type_witness %.3 [template = constants.%.4] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%B @@ -530,25 +531,25 @@ var b: B = {.x = 1} as B; // CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %.loc13_25: Core.IntLiteral = int_value 1 [template = constants.%.7] -// CHECK:STDOUT: %.loc13_33: Core.IntLiteral = int_value 2 [template = constants.%.8] -// CHECK:STDOUT: %.loc13_34.1: %.9 = struct_literal (%.loc13_25, %.loc13_33) +// CHECK:STDOUT: %.loc13_25: Core.IntLiteral = int_value 1 [template = constants.%.6] +// CHECK:STDOUT: %.loc13_33: Core.IntLiteral = int_value 2 [template = constants.%.7] +// CHECK:STDOUT: %.loc13_34.1: %.8 = struct_literal (%.loc13_25, %.loc13_33) // CHECK:STDOUT: %A.ref.loc13: type = name_ref A, file.%A.decl [template = constants.%A] -// CHECK:STDOUT: %.loc13_34.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.14] -// CHECK:STDOUT: %.loc13_34.3: = bound_method %.loc13_25, %.loc13_34.2 [template = constants.%.30] -// CHECK:STDOUT: %.loc13_34.4: = specific_function %.loc13_34.3, @Convert.2(constants.%.1) [template = constants.%.31] -// CHECK:STDOUT: %int.convert_checked.loc13_34.1: init %i32 = call %.loc13_34.4(%.loc13_25) [template = constants.%.32] -// CHECK:STDOUT: %.loc13_34.5: init %i32 = converted %.loc13_25, %int.convert_checked.loc13_34.1 [template = constants.%.32] +// CHECK:STDOUT: %.loc13_34.2: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.14] +// CHECK:STDOUT: %.loc13_34.3: = bound_method %.loc13_25, %.loc13_34.2 [template = constants.%.29] +// CHECK:STDOUT: %.loc13_34.4: = specific_function %.loc13_34.3, @Convert.2(constants.%.1) [template = constants.%.30] +// CHECK:STDOUT: %int.convert_checked.loc13_34.1: init %i32 = call %.loc13_34.4(%.loc13_25) [template = constants.%.31] +// CHECK:STDOUT: %.loc13_34.5: init %i32 = converted %.loc13_25, %int.convert_checked.loc13_34.1 [template = constants.%.31] // CHECK:STDOUT: %.loc13_34.6: ref %A = temporary_storage // CHECK:STDOUT: %.loc13_34.7: ref %i32 = class_element_access %.loc13_34.6, element0 -// CHECK:STDOUT: %.loc13_34.8: init %i32 = initialize_from %.loc13_34.5 to %.loc13_34.7 [template = constants.%.32] -// CHECK:STDOUT: %.loc13_34.9: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.14] -// CHECK:STDOUT: %.loc13_34.10: = bound_method %.loc13_33, %.loc13_34.9 [template = constants.%.33] -// CHECK:STDOUT: %.loc13_34.11: = specific_function %.loc13_34.10, @Convert.2(constants.%.1) [template = constants.%.34] -// CHECK:STDOUT: %int.convert_checked.loc13_34.2: init %i32 = call %.loc13_34.11(%.loc13_33) [template = constants.%.35] -// CHECK:STDOUT: %.loc13_34.12: init %i32 = converted %.loc13_33, %int.convert_checked.loc13_34.2 [template = constants.%.35] +// CHECK:STDOUT: %.loc13_34.8: init %i32 = initialize_from %.loc13_34.5 to %.loc13_34.7 [template = constants.%.31] +// CHECK:STDOUT: %.loc13_34.9: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.14] +// CHECK:STDOUT: %.loc13_34.10: = bound_method %.loc13_33, %.loc13_34.9 [template = constants.%.32] +// CHECK:STDOUT: %.loc13_34.11: = specific_function %.loc13_34.10, @Convert.2(constants.%.1) [template = constants.%.33] +// CHECK:STDOUT: %int.convert_checked.loc13_34.2: init %i32 = call %.loc13_34.11(%.loc13_33) [template = constants.%.34] +// CHECK:STDOUT: %.loc13_34.12: init %i32 = converted %.loc13_33, %int.convert_checked.loc13_34.2 [template = constants.%.34] // CHECK:STDOUT: %.loc13_34.13: ref %i32 = class_element_access %.loc13_34.6, element1 -// CHECK:STDOUT: %.loc13_34.14: init %i32 = initialize_from %.loc13_34.12 to %.loc13_34.13 [template = constants.%.35] +// CHECK:STDOUT: %.loc13_34.14: init %i32 = initialize_from %.loc13_34.12 to %.loc13_34.13 [template = constants.%.34] // CHECK:STDOUT: %.loc13_34.15: init %A = class_init (%.loc13_34.8, %.loc13_34.14), %.loc13_34.6 [template = constants.%struct] // CHECK:STDOUT: %.loc13_34.16: ref %A = temporary %.loc13_34.6, %.loc13_34.15 // CHECK:STDOUT: %.loc13_36: ref %A = converted %.loc13_34.1, %.loc13_34.16 @@ -557,25 +558,25 @@ var b: B = {.x = 1} as B; // CHECK:STDOUT: %.loc13_42.2: ref %B = converted %.loc13_36, %.loc13_42.1 // CHECK:STDOUT: %.loc13_42.3: %B = bind_value %.loc13_42.2 // CHECK:STDOUT: %b_value: %B = bind_name b_value, %.loc13_42.3 -// CHECK:STDOUT: %.loc24_24: Core.IntLiteral = int_value 1 [template = constants.%.7] -// CHECK:STDOUT: %.loc24_32: Core.IntLiteral = int_value 2 [template = constants.%.8] -// CHECK:STDOUT: %.loc24_33.1: %.9 = struct_literal (%.loc24_24, %.loc24_32) +// CHECK:STDOUT: %.loc24_24: Core.IntLiteral = int_value 1 [template = constants.%.6] +// CHECK:STDOUT: %.loc24_32: Core.IntLiteral = int_value 2 [template = constants.%.7] +// CHECK:STDOUT: %.loc24_33.1: %.8 = struct_literal (%.loc24_24, %.loc24_32) // CHECK:STDOUT: %A.ref.loc24: type = name_ref A, file.%A.decl [template = constants.%A] -// CHECK:STDOUT: %.loc24_33.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.14] -// CHECK:STDOUT: %.loc24_33.3: = bound_method %.loc24_24, %.loc24_33.2 [template = constants.%.30] -// CHECK:STDOUT: %.loc24_33.4: = specific_function %.loc24_33.3, @Convert.2(constants.%.1) [template = constants.%.31] -// CHECK:STDOUT: %int.convert_checked.loc24_33.1: init %i32 = call %.loc24_33.4(%.loc24_24) [template = constants.%.32] -// CHECK:STDOUT: %.loc24_33.5: init %i32 = converted %.loc24_24, %int.convert_checked.loc24_33.1 [template = constants.%.32] +// CHECK:STDOUT: %.loc24_33.2: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.14] +// CHECK:STDOUT: %.loc24_33.3: = bound_method %.loc24_24, %.loc24_33.2 [template = constants.%.29] +// CHECK:STDOUT: %.loc24_33.4: = specific_function %.loc24_33.3, @Convert.2(constants.%.1) [template = constants.%.30] +// CHECK:STDOUT: %int.convert_checked.loc24_33.1: init %i32 = call %.loc24_33.4(%.loc24_24) [template = constants.%.31] +// CHECK:STDOUT: %.loc24_33.5: init %i32 = converted %.loc24_24, %int.convert_checked.loc24_33.1 [template = constants.%.31] // CHECK:STDOUT: %.loc24_33.6: ref %A = temporary_storage // CHECK:STDOUT: %.loc24_33.7: ref %i32 = class_element_access %.loc24_33.6, element0 -// CHECK:STDOUT: %.loc24_33.8: init %i32 = initialize_from %.loc24_33.5 to %.loc24_33.7 [template = constants.%.32] -// CHECK:STDOUT: %.loc24_33.9: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.14] -// CHECK:STDOUT: %.loc24_33.10: = bound_method %.loc24_32, %.loc24_33.9 [template = constants.%.33] -// CHECK:STDOUT: %.loc24_33.11: = specific_function %.loc24_33.10, @Convert.2(constants.%.1) [template = constants.%.34] -// CHECK:STDOUT: %int.convert_checked.loc24_33.2: init %i32 = call %.loc24_33.11(%.loc24_32) [template = constants.%.35] -// CHECK:STDOUT: %.loc24_33.12: init %i32 = converted %.loc24_32, %int.convert_checked.loc24_33.2 [template = constants.%.35] +// CHECK:STDOUT: %.loc24_33.8: init %i32 = initialize_from %.loc24_33.5 to %.loc24_33.7 [template = constants.%.31] +// CHECK:STDOUT: %.loc24_33.9: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.14] +// CHECK:STDOUT: %.loc24_33.10: = bound_method %.loc24_32, %.loc24_33.9 [template = constants.%.32] +// CHECK:STDOUT: %.loc24_33.11: = specific_function %.loc24_33.10, @Convert.2(constants.%.1) [template = constants.%.33] +// CHECK:STDOUT: %int.convert_checked.loc24_33.2: init %i32 = call %.loc24_33.11(%.loc24_32) [template = constants.%.34] +// CHECK:STDOUT: %.loc24_33.12: init %i32 = converted %.loc24_32, %int.convert_checked.loc24_33.2 [template = constants.%.34] // CHECK:STDOUT: %.loc24_33.13: ref %i32 = class_element_access %.loc24_33.6, element1 -// CHECK:STDOUT: %.loc24_33.14: init %i32 = initialize_from %.loc24_33.12 to %.loc24_33.13 [template = constants.%.35] +// CHECK:STDOUT: %.loc24_33.14: init %i32 = initialize_from %.loc24_33.12 to %.loc24_33.13 [template = constants.%.34] // CHECK:STDOUT: %.loc24_33.15: init %A = class_init (%.loc24_33.8, %.loc24_33.14), %.loc24_33.6 [template = constants.%struct] // CHECK:STDOUT: %.loc24_33.16: ref %A = temporary %.loc24_33.6, %.loc24_33.15 // CHECK:STDOUT: %.loc24_35: ref %A = converted %.loc24_33.1, %.loc24_33.16 @@ -599,9 +600,8 @@ var b: B = {.x = 1} as B; // CHECK:STDOUT: %.3: type = struct_type {.x: %i32} [template] // CHECK:STDOUT: %.4: = complete_type_witness %.3 [template] // CHECK:STDOUT: %B: type = class_type @B [template] -// CHECK:STDOUT: %.6: = complete_type_witness %A [template] -// CHECK:STDOUT: %.7: Core.IntLiteral = int_value 1 [template] -// CHECK:STDOUT: %.8: type = struct_type {.x: Core.IntLiteral} [template] +// CHECK:STDOUT: %.6: Core.IntLiteral = int_value 1 [template] +// CHECK:STDOUT: %.7: type = struct_type {.x: Core.IntLiteral} [template] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -643,8 +643,8 @@ var b: B = {.x = 1} as B; // CHECK:STDOUT: // CHECK:STDOUT: class @B { // CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [template = constants.%A] -// CHECK:STDOUT: adapt_decl %A -// CHECK:STDOUT: %.loc10: = complete_type_witness %A [template = constants.%.6] +// CHECK:STDOUT: adapt_decl %A.ref +// CHECK:STDOUT: %.loc10: = complete_type_witness %.3 [template = constants.%.4] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%B @@ -652,8 +652,8 @@ var b: B = {.x = 1} as B; // CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %.loc21_18: Core.IntLiteral = int_value 1 [template = constants.%.7] -// CHECK:STDOUT: %.loc21_19: %.8 = struct_literal (%.loc21_18) +// CHECK:STDOUT: %.loc21_18: Core.IntLiteral = int_value 1 [template = constants.%.6] +// CHECK:STDOUT: %.loc21_19: %.7 = struct_literal (%.loc21_18) // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B] // CHECK:STDOUT: %.loc21_21: %B = converted %.loc21_19, [template = ] // CHECK:STDOUT: assign file.%b.var, diff --git a/toolchain/check/testdata/class/adapt.carbon b/toolchain/check/testdata/class/adapt.carbon index bc4fdd6dd3adb..4af5497d85f23 100644 --- a/toolchain/check/testdata/class/adapt.carbon +++ b/toolchain/check/testdata/class/adapt.carbon @@ -57,7 +57,6 @@ fn F(a: AdaptNotExtend) { // CHECK:STDOUT: %.3: type = struct_type {.a: %i32, .b: %i32} [template] // CHECK:STDOUT: %.4: = complete_type_witness %.3 [template] // CHECK:STDOUT: %SomeClassAdapter: type = class_type @SomeClassAdapter [template] -// CHECK:STDOUT: %.6: = complete_type_witness %SomeClass [template] // CHECK:STDOUT: %StructAdapter: type = class_type @StructAdapter [template] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -103,8 +102,8 @@ fn F(a: AdaptNotExtend) { // CHECK:STDOUT: // CHECK:STDOUT: class @SomeClassAdapter { // CHECK:STDOUT: %SomeClass.ref: type = name_ref SomeClass, file.%SomeClass.decl [template = constants.%SomeClass] -// CHECK:STDOUT: adapt_decl %SomeClass -// CHECK:STDOUT: %.loc11: = complete_type_witness %SomeClass [template = constants.%.6] +// CHECK:STDOUT: adapt_decl %SomeClass.ref +// CHECK:STDOUT: %.loc11: = complete_type_witness %.3 [template = constants.%.4] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%SomeClassAdapter @@ -120,7 +119,7 @@ fn F(a: AdaptNotExtend) { // CHECK:STDOUT: %.loc14_23.2: type = value_of_initializer %int.make_type_signed.loc14_23 [template = constants.%i32] // CHECK:STDOUT: %.loc14_23.3: type = converted %int.make_type_signed.loc14_23, %.loc14_23.2 [template = constants.%i32] // CHECK:STDOUT: %.loc14_26: type = struct_type {.a: %i32, .b: %i32} [template = constants.%.3] -// CHECK:STDOUT: adapt_decl %.3 +// CHECK:STDOUT: adapt_decl %.loc14_26 // CHECK:STDOUT: %.loc15: = complete_type_witness %.3 [template = constants.%.4] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -136,7 +135,6 @@ fn F(a: AdaptNotExtend) { // CHECK:STDOUT: %.1: type = struct_type {} [template] // CHECK:STDOUT: %.2: = complete_type_witness %.1 [template] // CHECK:STDOUT: %AdaptNotExtend: type = class_type @AdaptNotExtend [template] -// CHECK:STDOUT: %.4: = complete_type_witness %Adapted [template] // CHECK:STDOUT: %F.type.2: type = fn_type @F.2 [template] // CHECK:STDOUT: %F.2: %F.type.2 = struct_value () [template] // CHECK:STDOUT: } @@ -179,8 +177,8 @@ fn F(a: AdaptNotExtend) { // CHECK:STDOUT: // CHECK:STDOUT: class @AdaptNotExtend { // CHECK:STDOUT: %Adapted.ref: type = name_ref Adapted, file.%Adapted.decl [template = constants.%Adapted] -// CHECK:STDOUT: adapt_decl %Adapted -// CHECK:STDOUT: %.loc10: = complete_type_witness %Adapted [template = constants.%.4] +// CHECK:STDOUT: adapt_decl %Adapted.ref +// CHECK:STDOUT: %.loc10: = complete_type_witness %.1 [template = constants.%.2] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%AdaptNotExtend diff --git a/toolchain/check/testdata/class/base.carbon b/toolchain/check/testdata/class/base.carbon index 46509a9c9db9f..faa17405be070 100644 --- a/toolchain/check/testdata/class/base.carbon +++ b/toolchain/check/testdata/class/base.carbon @@ -151,7 +151,7 @@ class Derived { // CHECK:STDOUT: // CHECK:STDOUT: class @Derived { // CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base] -// CHECK:STDOUT: %.loc8: %.6 = base_decl %Base, element0 [template] +// CHECK:STDOUT: %.loc8: %.6 = base_decl %Base.ref, element0 [template] // CHECK:STDOUT: %.loc10_10.1: Core.IntLiteral = int_value 32 [template = constants.%.1] // CHECK:STDOUT: %int.make_type_signed: init type = call constants.%Int(%.loc10_10.1) [template = constants.%i32] // CHECK:STDOUT: %.loc10_10.2: type = value_of_initializer %int.make_type_signed [template = constants.%i32] diff --git a/toolchain/check/testdata/class/base_field.carbon b/toolchain/check/testdata/class/base_field.carbon index dbc271d75c833..9127cf7434588 100644 --- a/toolchain/check/testdata/class/base_field.carbon +++ b/toolchain/check/testdata/class/base_field.carbon @@ -112,7 +112,7 @@ fn Access(p: Derived*) -> i32* { // CHECK:STDOUT: // CHECK:STDOUT: class @Derived { // CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base] -// CHECK:STDOUT: %.loc18: %.6 = base_decl %Base, element0 [template] +// CHECK:STDOUT: %.loc18: %.6 = base_decl %Base.ref, element0 [template] // CHECK:STDOUT: %.loc20_10.1: Core.IntLiteral = int_value 32 [template = constants.%.1] // CHECK:STDOUT: %int.make_type_signed.loc20: init type = call constants.%Int(%.loc20_10.1) [template = constants.%i32] // CHECK:STDOUT: %.loc20_10.2: type = value_of_initializer %int.make_type_signed.loc20 [template = constants.%i32] diff --git a/toolchain/check/testdata/class/base_function_unqualified.carbon b/toolchain/check/testdata/class/base_function_unqualified.carbon index ce9070017907e..440b0e3f0b609 100644 --- a/toolchain/check/testdata/class/base_function_unqualified.carbon +++ b/toolchain/check/testdata/class/base_function_unqualified.carbon @@ -72,7 +72,7 @@ fn Derived.H() { // CHECK:STDOUT: // CHECK:STDOUT: class @Derived { // CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base] -// CHECK:STDOUT: %.loc16: %.4 = base_decl %Base, element0 [template] +// CHECK:STDOUT: %.loc16: %.4 = base_decl %Base.ref, element0 [template] // CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [template = constants.%G] {} {} // CHECK:STDOUT: %H.decl: %H.type = fn_decl @H [template = constants.%H] {} {} // CHECK:STDOUT: %.loc20: = complete_type_witness %.5 [template = constants.%.6] diff --git a/toolchain/check/testdata/class/base_method.carbon b/toolchain/check/testdata/class/base_method.carbon index 921337824b942..7f39bd177910d 100644 --- a/toolchain/check/testdata/class/base_method.carbon +++ b/toolchain/check/testdata/class/base_method.carbon @@ -124,7 +124,7 @@ fn Call(p: Derived*) { // CHECK:STDOUT: // CHECK:STDOUT: class @Derived { // CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base] -// CHECK:STDOUT: %.loc22: %.31 = base_decl %Base, element0 [template] +// CHECK:STDOUT: %.loc22: %.31 = base_decl %Base.ref, element0 [template] // CHECK:STDOUT: %.loc23: = complete_type_witness %.32 [template = constants.%.33] // CHECK:STDOUT: // CHECK:STDOUT: !members: diff --git a/toolchain/check/testdata/class/base_method_qualified.carbon b/toolchain/check/testdata/class/base_method_qualified.carbon index 0727ee83bb2e1..5e3ce4eb90bfc 100644 --- a/toolchain/check/testdata/class/base_method_qualified.carbon +++ b/toolchain/check/testdata/class/base_method_qualified.carbon @@ -163,7 +163,7 @@ fn PassDerivedToBaseIndirect(p: Derived*) -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: class @Derived { // CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base] -// CHECK:STDOUT: %.loc19: %.5 = base_decl %Base, element0 [template] +// CHECK:STDOUT: %.loc19: %.5 = base_decl %Base.ref, element0 [template] // CHECK:STDOUT: %F.decl: %F.type.2 = fn_decl @F.2 [template = constants.%F.2] { // CHECK:STDOUT: %self.patt: %Derived = binding_pattern self // CHECK:STDOUT: %self.param_patt: %Derived = value_param_pattern %self.patt, runtime_param0 diff --git a/toolchain/check/testdata/class/base_method_shadow.carbon b/toolchain/check/testdata/class/base_method_shadow.carbon index 54be9bae61bfa..8ec252a242143 100644 --- a/toolchain/check/testdata/class/base_method_shadow.carbon +++ b/toolchain/check/testdata/class/base_method_shadow.carbon @@ -134,7 +134,7 @@ fn Call(a: A*, b: B*, c: C*, d: D*) { // CHECK:STDOUT: // CHECK:STDOUT: class @B { // CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [template = constants.%A] -// CHECK:STDOUT: %.loc16: %.5 = base_decl %A, element0 [template] +// CHECK:STDOUT: %.loc16: %.5 = base_decl %A.ref, element0 [template] // CHECK:STDOUT: %F.decl: %F.type.2 = fn_decl @F.2 [template = constants.%F.2] { // CHECK:STDOUT: %self.patt: %.6 = binding_pattern self // CHECK:STDOUT: %self.param_patt: %.6 = value_param_pattern %self.patt, runtime_param0 @@ -156,7 +156,7 @@ fn Call(a: A*, b: B*, c: C*, d: D*) { // CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B] -// CHECK:STDOUT: %.loc21: %.11 = base_decl %B, element0 [template] +// CHECK:STDOUT: %.loc21: %.11 = base_decl %B.ref, element0 [template] // CHECK:STDOUT: %F.decl: %F.type.3 = fn_decl @F.3 [template = constants.%F.3] { // CHECK:STDOUT: %self.patt: %.12 = binding_pattern self // CHECK:STDOUT: %self.param_patt: %.12 = value_param_pattern %self.patt, runtime_param0 @@ -178,7 +178,7 @@ fn Call(a: A*, b: B*, c: C*, d: D*) { // CHECK:STDOUT: // CHECK:STDOUT: class @D { // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B] -// CHECK:STDOUT: %.loc26: %.15 = base_decl %B, element0 [template] +// CHECK:STDOUT: %.loc26: %.15 = base_decl %B.ref, element0 [template] // CHECK:STDOUT: %.loc27: = complete_type_witness %.13 [template = constants.%.14] // CHECK:STDOUT: // CHECK:STDOUT: !members: diff --git a/toolchain/check/testdata/class/compound_field.carbon b/toolchain/check/testdata/class/compound_field.carbon index ab87712b84acb..36e4dcd027e96 100644 --- a/toolchain/check/testdata/class/compound_field.carbon +++ b/toolchain/check/testdata/class/compound_field.carbon @@ -183,7 +183,7 @@ fn AccessBaseIndirect(p: Derived*) -> i32* { // CHECK:STDOUT: // CHECK:STDOUT: class @Derived { // CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base] -// CHECK:STDOUT: %.loc18: %.6 = base_decl %Base, element0 [template] +// CHECK:STDOUT: %.loc18: %.6 = base_decl %Base.ref, element0 [template] // CHECK:STDOUT: %.loc20_10.1: Core.IntLiteral = int_value 32 [template = constants.%.1] // CHECK:STDOUT: %int.make_type_signed.loc20: init type = call constants.%Int(%.loc20_10.1) [template = constants.%i32] // CHECK:STDOUT: %.loc20_10.2: type = value_of_initializer %int.make_type_signed.loc20 [template = constants.%i32] diff --git a/toolchain/check/testdata/class/derived_to_base.carbon b/toolchain/check/testdata/class/derived_to_base.carbon index ca6e53ccd8a8d..ceb43a8a36642 100644 --- a/toolchain/check/testdata/class/derived_to_base.carbon +++ b/toolchain/check/testdata/class/derived_to_base.carbon @@ -210,7 +210,7 @@ fn ConvertInit() { // CHECK:STDOUT: // CHECK:STDOUT: class @B { // CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [template = constants.%A] -// CHECK:STDOUT: %.loc16: %.6 = base_decl %A, element0 [template] +// CHECK:STDOUT: %.loc16: %.6 = base_decl %A.ref, element0 [template] // CHECK:STDOUT: %.loc17_10.1: Core.IntLiteral = int_value 32 [template = constants.%.1] // CHECK:STDOUT: %int.make_type_signed: init type = call constants.%Int(%.loc17_10.1) [template = constants.%i32] // CHECK:STDOUT: %.loc17_10.2: type = value_of_initializer %int.make_type_signed [template = constants.%i32] @@ -227,7 +227,7 @@ fn ConvertInit() { // CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B] -// CHECK:STDOUT: %.loc21: %.13 = base_decl %B, element0 [template] +// CHECK:STDOUT: %.loc21: %.13 = base_decl %B.ref, element0 [template] // CHECK:STDOUT: %.loc22_10.1: Core.IntLiteral = int_value 32 [template = constants.%.1] // CHECK:STDOUT: %int.make_type_signed: init type = call constants.%Int(%.loc22_10.1) [template = constants.%i32] // CHECK:STDOUT: %.loc22_10.2: type = value_of_initializer %int.make_type_signed [template = constants.%i32] diff --git a/toolchain/check/testdata/class/extend_adapt.carbon b/toolchain/check/testdata/class/extend_adapt.carbon index a245a56183baa..e82f1aef71a9a 100644 --- a/toolchain/check/testdata/class/extend_adapt.carbon +++ b/toolchain/check/testdata/class/extend_adapt.carbon @@ -154,7 +154,6 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: %AdapterMethod: %AdapterMethod.type = struct_value () [template] // CHECK:STDOUT: %.3: type = struct_type {.a: %i32, .b: %i32} [template] // CHECK:STDOUT: %.4: = complete_type_witness %.3 [template] -// CHECK:STDOUT: %.6: = complete_type_witness %SomeClass [template] // CHECK:STDOUT: %TestStaticMemberFunction.type: type = fn_type @TestStaticMemberFunction [template] // CHECK:STDOUT: %TestStaticMemberFunction: %TestStaticMemberFunction.type = struct_value () [template] // CHECK:STDOUT: %TestAdapterMethod.type: type = fn_type @TestAdapterMethod [template] @@ -201,8 +200,8 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: class @SomeClassAdapter { // CHECK:STDOUT: %SomeClass.ref: type = name_ref SomeClass, file.%SomeClass.decl [template = constants.%SomeClass] -// CHECK:STDOUT: adapt_decl %SomeClass -// CHECK:STDOUT: %.loc17: = complete_type_witness %SomeClass [template = constants.%.6] +// CHECK:STDOUT: adapt_decl %SomeClass.ref +// CHECK:STDOUT: %.loc17: = complete_type_witness %.3 [template = constants.%.4] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%SomeClassAdapter @@ -270,7 +269,6 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: %.1: type = struct_type {} [template] // CHECK:STDOUT: %.2: = complete_type_witness %.1 [template] // CHECK:STDOUT: %SomeClassAdapter: type = class_type @SomeClassAdapter [template] -// CHECK:STDOUT: %.4: = complete_type_witness %SomeClass [template] // CHECK:STDOUT: %F.type.2: type = fn_type @F.2 [template] // CHECK:STDOUT: %F.2: %F.type.2 = struct_value () [template] // CHECK:STDOUT: } @@ -321,8 +319,8 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: class @SomeClassAdapter { // CHECK:STDOUT: %SomeClass.ref: type = name_ref SomeClass, file.%SomeClass.decl [template = constants.%SomeClass] -// CHECK:STDOUT: adapt_decl %SomeClass -// CHECK:STDOUT: %.loc10: = complete_type_witness %SomeClass [template = constants.%.4] +// CHECK:STDOUT: adapt_decl %SomeClass.ref +// CHECK:STDOUT: %.loc10: = complete_type_witness %.1 [template = constants.%.2] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%SomeClassAdapter @@ -353,7 +351,6 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: %.3: type = struct_type {.a: %i32, .b: %i32} [template] // CHECK:STDOUT: %.4: = complete_type_witness %.3 [template] // CHECK:STDOUT: %SomeClassAdapter: type = class_type @SomeClassAdapter [template] -// CHECK:STDOUT: %.6: = complete_type_witness %SomeClass [template] // CHECK:STDOUT: %F.type: type = fn_type @F [template] // CHECK:STDOUT: %F: %F.type = struct_value () [template] // CHECK:STDOUT: } @@ -416,8 +413,8 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: class @SomeClassAdapter { // CHECK:STDOUT: %SomeClass.ref: type = name_ref SomeClass, file.%SomeClass.decl [template = constants.%SomeClass] -// CHECK:STDOUT: adapt_decl %SomeClass -// CHECK:STDOUT: %.loc11: = complete_type_witness %SomeClass [template = constants.%.6] +// CHECK:STDOUT: adapt_decl %SomeClass.ref +// CHECK:STDOUT: %.loc11: = complete_type_witness %.3 [template = constants.%.4] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%SomeClassAdapter @@ -491,7 +488,7 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: %.loc5_30.2: type = value_of_initializer %int.make_type_signed.loc5_30 [template = constants.%i32] // CHECK:STDOUT: %.loc5_30.3: type = converted %int.make_type_signed.loc5_30, %.loc5_30.2 [template = constants.%i32] // CHECK:STDOUT: %.loc5_33: type = struct_type {.a: %i32, .b: %i32} [template = constants.%.2] -// CHECK:STDOUT: adapt_decl %.2 +// CHECK:STDOUT: adapt_decl %.loc5_33 // CHECK:STDOUT: %.loc6: = complete_type_witness %.2 [template = constants.%.4] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -567,7 +564,7 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: %.loc5_26.3: type = value_of_initializer %int.make_type_signed.loc5_22 [template = constants.%i32] // CHECK:STDOUT: %.loc5_26.4: type = converted %int.make_type_signed.loc5_22, %.loc5_26.3 [template = constants.%i32] // CHECK:STDOUT: %.loc5_26.5: type = converted %.loc5_25, constants.%tuple.type.2 [template = constants.%tuple.type.2] -// CHECK:STDOUT: adapt_decl %tuple.type.2 +// CHECK:STDOUT: adapt_decl %.loc5_26.5 // CHECK:STDOUT: %.loc6: = complete_type_witness %tuple.type.2 [template = constants.%.3] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -658,7 +655,7 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: %int.make_type_signed: init type = call %MakeInt.ref(%.loc7_24) [template = constants.%i32] // CHECK:STDOUT: %.loc7_27.1: type = value_of_initializer %int.make_type_signed [template = constants.%i32] // CHECK:STDOUT: %.loc7_27.2: type = converted %int.make_type_signed, %.loc7_27.1 [template = constants.%i32] -// CHECK:STDOUT: adapt_decl %i32 +// CHECK:STDOUT: adapt_decl %.loc7_27.2 // CHECK:STDOUT: %.loc8: = complete_type_witness %i32 [template = constants.%.2] // CHECK:STDOUT: // CHECK:STDOUT: !members: diff --git a/toolchain/check/testdata/class/fail_abstract.carbon b/toolchain/check/testdata/class/fail_abstract.carbon index 584b23d677b08..ae2425d7777f5 100644 --- a/toolchain/check/testdata/class/fail_abstract.carbon +++ b/toolchain/check/testdata/class/fail_abstract.carbon @@ -492,7 +492,7 @@ fn CallReturnAbstract() { // CHECK:STDOUT: // CHECK:STDOUT: class @Derived { // CHECK:STDOUT: %Abstract.ref: type = name_ref Abstract, file.%Abstract.decl [template = constants.%Abstract] -// CHECK:STDOUT: %.loc8: %.4 = base_decl %Abstract, element0 [template] +// CHECK:STDOUT: %.loc8: %.4 = base_decl %Abstract.ref, element0 [template] // CHECK:STDOUT: %.loc10_10.1: Core.IntLiteral = int_value 32 [template = constants.%.5] // CHECK:STDOUT: %int.make_type_signed: init type = call constants.%Int(%.loc10_10.1) [template = constants.%i32] // CHECK:STDOUT: %.loc10_10.2: type = value_of_initializer %int.make_type_signed [template = constants.%i32] @@ -577,7 +577,7 @@ fn CallReturnAbstract() { // CHECK:STDOUT: // CHECK:STDOUT: class @Derived { // CHECK:STDOUT: %Abstract.ref: type = name_ref Abstract, file.%Abstract.decl [template = constants.%Abstract] -// CHECK:STDOUT: %.loc8: %.4 = base_decl %Abstract, element0 [template] +// CHECK:STDOUT: %.loc8: %.4 = base_decl %Abstract.ref, element0 [template] // CHECK:STDOUT: %.loc10_10.1: Core.IntLiteral = int_value 32 [template = constants.%.5] // CHECK:STDOUT: %int.make_type_signed: init type = call constants.%Int(%.loc10_10.1) [template = constants.%i32] // CHECK:STDOUT: %.loc10_10.2: type = value_of_initializer %int.make_type_signed [template = constants.%i32] @@ -669,7 +669,7 @@ fn CallReturnAbstract() { // CHECK:STDOUT: // CHECK:STDOUT: class @Derived { // CHECK:STDOUT: %Abstract.ref: type = name_ref Abstract, file.%Abstract.decl [template = constants.%Abstract] -// CHECK:STDOUT: %.loc9: %.6 = base_decl %Abstract, element0 [template] +// CHECK:STDOUT: %.loc9: %.6 = base_decl %Abstract.ref, element0 [template] // CHECK:STDOUT: %.loc11_10.1: Core.IntLiteral = int_value 32 [template = constants.%.1] // CHECK:STDOUT: %int.make_type_signed: init type = call constants.%Int(%.loc11_10.1) [template = constants.%i32] // CHECK:STDOUT: %.loc11_10.2: type = value_of_initializer %int.make_type_signed [template = constants.%i32] diff --git a/toolchain/check/testdata/class/fail_adapt_bad_decl.carbon b/toolchain/check/testdata/class/fail_adapt_bad_decl.carbon index 253ef03fa2574..0bf44aace8dbe 100644 --- a/toolchain/check/testdata/class/fail_adapt_bad_decl.carbon +++ b/toolchain/check/testdata/class/fail_adapt_bad_decl.carbon @@ -238,7 +238,7 @@ class C { // CHECK:STDOUT: class @MultipleAdapts { // CHECK:STDOUT: %.loc5_10: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc5_11: type = converted %.loc5_10, constants.%empty_tuple.type [template = constants.%empty_tuple.type] -// CHECK:STDOUT: adapt_decl %empty_tuple.type +// CHECK:STDOUT: adapt_decl %.loc5_11 // CHECK:STDOUT: %.loc13: %.1 = struct_literal () // CHECK:STDOUT: %.loc14: = complete_type_witness %empty_tuple.type [template = constants.%.2] // CHECK:STDOUT: @@ -249,7 +249,7 @@ class C { // CHECK:STDOUT: class @MultipleAdaptsSameType { // CHECK:STDOUT: %.loc17_10: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc17_11: type = converted %.loc17_10, constants.%empty_tuple.type [template = constants.%empty_tuple.type] -// CHECK:STDOUT: adapt_decl %empty_tuple.type +// CHECK:STDOUT: adapt_decl %.loc17_11 // CHECK:STDOUT: %.loc25: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc26: = complete_type_witness %empty_tuple.type [template = constants.%.2] // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/fail_adapt_modifiers.carbon b/toolchain/check/testdata/class/fail_adapt_modifiers.carbon index 8ca995fcc4117..3f220a98b9851 100644 --- a/toolchain/check/testdata/class/fail_adapt_modifiers.carbon +++ b/toolchain/check/testdata/class/fail_adapt_modifiers.carbon @@ -62,7 +62,6 @@ class C5 { // CHECK:STDOUT: %.1: type = struct_type {} [template] // CHECK:STDOUT: %.2: = complete_type_witness %.1 [template] // CHECK:STDOUT: %C1: type = class_type @C1 [template] -// CHECK:STDOUT: %.4: = complete_type_witness %B [template] // CHECK:STDOUT: %C2: type = class_type @C2 [template] // CHECK:STDOUT: %C3: type = class_type @C3 [template] // CHECK:STDOUT: %C4: type = class_type @C4 [template] @@ -104,8 +103,8 @@ class C5 { // CHECK:STDOUT: // CHECK:STDOUT: class @C1 { // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B] -// CHECK:STDOUT: adapt_decl %B -// CHECK:STDOUT: %.loc19: = complete_type_witness %B [template = constants.%.4] +// CHECK:STDOUT: adapt_decl %B.ref +// CHECK:STDOUT: %.loc19: = complete_type_witness %.1 [template = constants.%.2] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%C1 @@ -113,8 +112,8 @@ class C5 { // CHECK:STDOUT: // CHECK:STDOUT: class @C2 { // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B] -// CHECK:STDOUT: adapt_decl %B -// CHECK:STDOUT: %.loc27: = complete_type_witness %B [template = constants.%.4] +// CHECK:STDOUT: adapt_decl %B.ref +// CHECK:STDOUT: %.loc27: = complete_type_witness %.1 [template = constants.%.2] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%C2 @@ -122,8 +121,8 @@ class C5 { // CHECK:STDOUT: // CHECK:STDOUT: class @C3 { // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B] -// CHECK:STDOUT: adapt_decl %B -// CHECK:STDOUT: %.loc35: = complete_type_witness %B [template = constants.%.4] +// CHECK:STDOUT: adapt_decl %B.ref +// CHECK:STDOUT: %.loc35: = complete_type_witness %.1 [template = constants.%.2] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%C3 @@ -131,8 +130,8 @@ class C5 { // CHECK:STDOUT: // CHECK:STDOUT: class @C4 { // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B] -// CHECK:STDOUT: adapt_decl %B -// CHECK:STDOUT: %.loc46: = complete_type_witness %B [template = constants.%.4] +// CHECK:STDOUT: adapt_decl %B.ref +// CHECK:STDOUT: %.loc46: = complete_type_witness %.1 [template = constants.%.2] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%C4 @@ -141,8 +140,8 @@ class C5 { // CHECK:STDOUT: // CHECK:STDOUT: class @C5 { // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B] -// CHECK:STDOUT: adapt_decl %B -// CHECK:STDOUT: %.loc56: = complete_type_witness %B [template = constants.%.4] +// CHECK:STDOUT: adapt_decl %B.ref +// CHECK:STDOUT: %.loc56: = complete_type_witness %.1 [template = constants.%.2] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%C5 diff --git a/toolchain/check/testdata/class/fail_adapt_with_base.carbon b/toolchain/check/testdata/class/fail_adapt_with_base.carbon index 3203c796be446..f5052dca21f5a 100644 --- a/toolchain/check/testdata/class/fail_adapt_with_base.carbon +++ b/toolchain/check/testdata/class/fail_adapt_with_base.carbon @@ -58,7 +58,7 @@ base class AdaptWithVirtual { // CHECK:STDOUT: class @AdaptWithVirtual { // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] {} {} // CHECK:STDOUT: %Simple.ref: type = name_ref Simple, file.%Simple.decl [template = constants.%Simple] -// CHECK:STDOUT: adapt_decl %Simple +// CHECK:STDOUT: adapt_decl %Simple.ref // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%AdaptWithVirtual diff --git a/toolchain/check/testdata/class/fail_adapt_with_subobjects.carbon b/toolchain/check/testdata/class/fail_adapt_with_subobjects.carbon index 79301649031a8..3cfb786b90e9f 100644 --- a/toolchain/check/testdata/class/fail_adapt_with_subobjects.carbon +++ b/toolchain/check/testdata/class/fail_adapt_with_subobjects.carbon @@ -119,9 +119,9 @@ class AdaptWithBaseAndFields { // CHECK:STDOUT: %int.make_type_signed: init type = call constants.%Int(%.loc10_9) [template = constants.%i32] // CHECK:STDOUT: %.loc10_12.1: type = value_of_initializer %int.make_type_signed [template = constants.%i32] // CHECK:STDOUT: %.loc10_12.2: type = converted %int.make_type_signed, %.loc10_12.1 [template = constants.%i32] -// CHECK:STDOUT: adapt_decl %i32 +// CHECK:STDOUT: adapt_decl %.loc10_12.2 // CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base] -// CHECK:STDOUT: %.loc15: %.5 = base_decl %Base, element0 [template] +// CHECK:STDOUT: %.loc15: %.5 = base_decl %Base.ref, element0 [template] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%AdaptWithBase @@ -166,7 +166,7 @@ class AdaptWithBaseAndFields { // CHECK:STDOUT: %int.make_type_signed.loc8: init type = call constants.%Int(%.loc8_9) [template = constants.%i32] // CHECK:STDOUT: %.loc8_12.1: type = value_of_initializer %int.make_type_signed.loc8 [template = constants.%i32] // CHECK:STDOUT: %.loc8_12.2: type = converted %int.make_type_signed.loc8, %.loc8_12.1 [template = constants.%i32] -// CHECK:STDOUT: adapt_decl %i32 +// CHECK:STDOUT: adapt_decl %.loc8_12.2 // CHECK:STDOUT: %.loc13_10.1: Core.IntLiteral = int_value 32 [template = constants.%.1] // CHECK:STDOUT: %int.make_type_signed.loc13: init type = call constants.%Int(%.loc13_10.1) [template = constants.%i32] // CHECK:STDOUT: %.loc13_10.2: type = value_of_initializer %int.make_type_signed.loc13 [template = constants.%i32] @@ -183,7 +183,7 @@ class AdaptWithBaseAndFields { // CHECK:STDOUT: %int.make_type_signed.loc20: init type = call constants.%Int(%.loc20_9) [template = constants.%i32] // CHECK:STDOUT: %.loc20_12.1: type = value_of_initializer %int.make_type_signed.loc20 [template = constants.%i32] // CHECK:STDOUT: %.loc20_12.2: type = converted %int.make_type_signed.loc20, %.loc20_12.1 [template = constants.%i32] -// CHECK:STDOUT: adapt_decl %i32 +// CHECK:STDOUT: adapt_decl %.loc20_12.2 // CHECK:STDOUT: %.loc25_10.1: Core.IntLiteral = int_value 32 [template = constants.%.1] // CHECK:STDOUT: %int.make_type_signed.loc25: init type = call constants.%Int(%.loc25_10.1) [template = constants.%i32] // CHECK:STDOUT: %.loc25_10.2: type = value_of_initializer %int.make_type_signed.loc25 [template = constants.%i32] @@ -250,7 +250,7 @@ class AdaptWithBaseAndFields { // CHECK:STDOUT: // CHECK:STDOUT: class @AdaptWithBaseAndFields { // CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base] -// CHECK:STDOUT: %.loc7: %.4 = base_decl %Base, element0 [template] +// CHECK:STDOUT: %.loc7: %.4 = base_decl %Base.ref, element0 [template] // CHECK:STDOUT: %.loc8_10.1: Core.IntLiteral = int_value 32 [template = constants.%.5] // CHECK:STDOUT: %int.make_type_signed: init type = call constants.%Int(%.loc8_10.1) [template = constants.%i32] // CHECK:STDOUT: %.loc8_10.2: type = value_of_initializer %int.make_type_signed [template = constants.%i32] @@ -258,7 +258,7 @@ class AdaptWithBaseAndFields { // CHECK:STDOUT: %.loc8_8: %.6 = field_decl n, element1 [template] // CHECK:STDOUT: %.loc15_10: %.1 = struct_literal () // CHECK:STDOUT: %.loc15_11: type = converted %.loc15_10, constants.%.1 [template = constants.%.1] -// CHECK:STDOUT: adapt_decl %.1 +// CHECK:STDOUT: adapt_decl %.loc15_11 // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%AdaptWithBaseAndFields diff --git a/toolchain/check/testdata/class/fail_base_bad_type.carbon b/toolchain/check/testdata/class/fail_base_bad_type.carbon index 3189bf60ac053..240239a5ce784 100644 --- a/toolchain/check/testdata/class/fail_base_bad_type.carbon +++ b/toolchain/check/testdata/class/fail_base_bad_type.carbon @@ -847,7 +847,7 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: class @DeriveFromFinal { // CHECK:STDOUT: %Final.ref: type = name_ref Final, file.%Final.decl [template = constants.%Final] -// CHECK:STDOUT: %.loc11: %.6 = base_decl %Final, element0 [template] +// CHECK:STDOUT: %.loc11: %.6 = base_decl %Final.ref, element0 [template] // CHECK:STDOUT: %.loc12: = complete_type_witness %.7 [template = constants.%.8] // CHECK:STDOUT: // CHECK:STDOUT: !members: diff --git a/toolchain/check/testdata/class/fail_base_method_define.carbon b/toolchain/check/testdata/class/fail_base_method_define.carbon index ce43b94d9ecf0..3b97ec7267063 100644 --- a/toolchain/check/testdata/class/fail_base_method_define.carbon +++ b/toolchain/check/testdata/class/fail_base_method_define.carbon @@ -94,7 +94,7 @@ fn D.C.F() {} // CHECK:STDOUT: // CHECK:STDOUT: class @D { // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B] -// CHECK:STDOUT: %.loc20: %.4 = base_decl %B, element0 [template] +// CHECK:STDOUT: %.loc20: %.4 = base_decl %B.ref, element0 [template] // CHECK:STDOUT: %.loc21: = complete_type_witness %.5 [template = constants.%.6] // CHECK:STDOUT: // CHECK:STDOUT: !members: diff --git a/toolchain/check/testdata/class/fail_base_modifiers.carbon b/toolchain/check/testdata/class/fail_base_modifiers.carbon index 69fd52c0bd25a..e653b45f33526 100644 --- a/toolchain/check/testdata/class/fail_base_modifiers.carbon +++ b/toolchain/check/testdata/class/fail_base_modifiers.carbon @@ -102,7 +102,7 @@ class C4 { // CHECK:STDOUT: // CHECK:STDOUT: class @C1 { // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B] -// CHECK:STDOUT: %.loc18: %.4 = base_decl %B, element0 [template] +// CHECK:STDOUT: %.loc18: %.4 = base_decl %B.ref, element0 [template] // CHECK:STDOUT: %.loc19: = complete_type_witness %.5 [template = constants.%.6] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -113,7 +113,7 @@ class C4 { // CHECK:STDOUT: // CHECK:STDOUT: class @C2 { // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B] -// CHECK:STDOUT: %.loc30: %.7 = base_decl %B, element0 [template] +// CHECK:STDOUT: %.loc30: %.7 = base_decl %B.ref, element0 [template] // CHECK:STDOUT: %.loc31: = complete_type_witness %.5 [template = constants.%.6] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -123,7 +123,7 @@ class C4 { // CHECK:STDOUT: // CHECK:STDOUT: class @C3 { // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B] -// CHECK:STDOUT: %.loc41: %.8 = base_decl %B, element0 [template] +// CHECK:STDOUT: %.loc41: %.8 = base_decl %B.ref, element0 [template] // CHECK:STDOUT: %.loc42: = complete_type_witness %.5 [template = constants.%.6] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -134,7 +134,7 @@ class C4 { // CHECK:STDOUT: // CHECK:STDOUT: class @C4 { // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B] -// CHECK:STDOUT: %.loc51: %.9 = base_decl %B, element0 [template] +// CHECK:STDOUT: %.loc51: %.9 = base_decl %B.ref, element0 [template] // CHECK:STDOUT: %.loc52: = complete_type_witness %.5 [template = constants.%.6] // CHECK:STDOUT: // CHECK:STDOUT: !members: diff --git a/toolchain/check/testdata/class/fail_base_no_extend.carbon b/toolchain/check/testdata/class/fail_base_no_extend.carbon index 4dce724b457d2..97db3fa855027 100644 --- a/toolchain/check/testdata/class/fail_base_no_extend.carbon +++ b/toolchain/check/testdata/class/fail_base_no_extend.carbon @@ -56,7 +56,7 @@ class C { // CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B] -// CHECK:STDOUT: %.loc17: %.4 = base_decl %B, element0 [template] +// CHECK:STDOUT: %.loc17: %.4 = base_decl %B.ref, element0 [template] // CHECK:STDOUT: %.loc18: = complete_type_witness %.5 [template = constants.%.6] // CHECK:STDOUT: // CHECK:STDOUT: !members: diff --git a/toolchain/check/testdata/class/fail_base_repeated.carbon b/toolchain/check/testdata/class/fail_base_repeated.carbon index bb7b042fed123..cee7d94a53d3b 100644 --- a/toolchain/check/testdata/class/fail_base_repeated.carbon +++ b/toolchain/check/testdata/class/fail_base_repeated.carbon @@ -88,7 +88,7 @@ class D { // CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %B1.ref: type = name_ref B1, file.%B1.decl [template = constants.%B1] -// CHECK:STDOUT: %.loc15: %.4 = base_decl %B1, element0 [template] +// CHECK:STDOUT: %.loc15: %.4 = base_decl %B1.ref, element0 [template] // CHECK:STDOUT: %B2.ref: type = name_ref B2, file.%B2.decl [template = constants.%B2] // CHECK:STDOUT: %.loc24: = complete_type_witness %.5 [template = constants.%.6] // CHECK:STDOUT: @@ -100,7 +100,7 @@ class D { // CHECK:STDOUT: // CHECK:STDOUT: class @D { // CHECK:STDOUT: %B1.ref.loc28: type = name_ref B1, file.%B1.decl [template = constants.%B1] -// CHECK:STDOUT: %.loc28: %.7 = base_decl %B1, element0 [template] +// CHECK:STDOUT: %.loc28: %.7 = base_decl %B1.ref.loc28, element0 [template] // CHECK:STDOUT: %B1.ref.loc35: type = name_ref B1, file.%B1.decl [template = constants.%B1] // CHECK:STDOUT: %.loc36: = complete_type_witness %.5 [template = constants.%.6] // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/fail_base_unbound.carbon b/toolchain/check/testdata/class/fail_base_unbound.carbon index 0e6bee10c84f5..c4d132df86e11 100644 --- a/toolchain/check/testdata/class/fail_base_unbound.carbon +++ b/toolchain/check/testdata/class/fail_base_unbound.carbon @@ -60,7 +60,7 @@ let b: B = C.base; // CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B] -// CHECK:STDOUT: %.loc14: %.4 = base_decl %B, element0 [template] +// CHECK:STDOUT: %.loc14: %.4 = base_decl %B.ref, element0 [template] // CHECK:STDOUT: %.loc15: = complete_type_witness %.5 [template = constants.%.6] // CHECK:STDOUT: // CHECK:STDOUT: !members: diff --git a/toolchain/check/testdata/class/fail_derived_to_base.carbon b/toolchain/check/testdata/class/fail_derived_to_base.carbon index c2bf80fe6081a..bf3f0fa7cbd26 100644 --- a/toolchain/check/testdata/class/fail_derived_to_base.carbon +++ b/toolchain/check/testdata/class/fail_derived_to_base.carbon @@ -153,7 +153,7 @@ fn ConvertIncomplete(p: Incomplete*) -> A2* { return p; } // CHECK:STDOUT: // CHECK:STDOUT: class @B2 { // CHECK:STDOUT: %A2.ref: type = name_ref A2, file.%A2.decl [template = constants.%A2] -// CHECK:STDOUT: %.loc20: %.7 = base_decl %A2, element0 [template] +// CHECK:STDOUT: %.loc20: %.7 = base_decl %A2.ref, element0 [template] // CHECK:STDOUT: %.loc21_10.1: Core.IntLiteral = int_value 32 [template = constants.%.1] // CHECK:STDOUT: %int.make_type_signed: init type = call constants.%Int(%.loc21_10.1) [template = constants.%i32] // CHECK:STDOUT: %.loc21_10.2: type = value_of_initializer %int.make_type_signed [template = constants.%i32] diff --git a/toolchain/check/testdata/class/fail_extend_cycle.carbon b/toolchain/check/testdata/class/fail_extend_cycle.carbon index 478e423d5d634..d97d5828c1884 100644 --- a/toolchain/check/testdata/class/fail_extend_cycle.carbon +++ b/toolchain/check/testdata/class/fail_extend_cycle.carbon @@ -73,7 +73,7 @@ base class A { // CHECK:STDOUT: // CHECK:STDOUT: class @B { // CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [template = constants.%A] -// CHECK:STDOUT: %.loc16: %.4 = base_decl %A, element0 [template] +// CHECK:STDOUT: %.loc16: %.4 = base_decl %A.ref, element0 [template] // CHECK:STDOUT: %.loc17: = complete_type_witness %.5 [template = constants.%.6] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -84,7 +84,7 @@ base class A { // CHECK:STDOUT: // CHECK:STDOUT: class @.1 { // CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [template = constants.%A] -// CHECK:STDOUT: %.loc27: %.8 = base_decl %A, element0 [template] +// CHECK:STDOUT: %.loc27: %.8 = base_decl %A.ref, element0 [template] // CHECK:STDOUT: %C.ref: = name_ref C, [template = ] // CHECK:STDOUT: %.loc31: = field_decl c, element1 [template] // CHECK:STDOUT: %.loc32: = complete_type_witness [template = ] diff --git a/toolchain/check/testdata/class/generic/base_is_generic.carbon b/toolchain/check/testdata/class/generic/base_is_generic.carbon index 9e709e99aca99..cd8e96c5719d2 100644 --- a/toolchain/check/testdata/class/generic/base_is_generic.carbon +++ b/toolchain/check/testdata/class/generic/base_is_generic.carbon @@ -197,7 +197,7 @@ fn H() { // CHECK:STDOUT: %Base.ref: %Base.type = name_ref Base, file.%Base.decl [template = constants.%Base.1] // CHECK:STDOUT: %Param.ref: type = name_ref Param, file.%Param.decl [template = constants.%Param] // CHECK:STDOUT: %Base: type = class_type @Base, @Base(constants.%Param) [template = constants.%Base.3] -// CHECK:STDOUT: %.loc13: %.14 = base_decl %Base.3, element0 [template] +// CHECK:STDOUT: %.loc13: %.14 = base_decl %Base, element0 [template] // CHECK:STDOUT: %.loc14: = complete_type_witness %.15 [template = constants.%.16] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -270,7 +270,7 @@ fn H() { // CHECK:STDOUT: %import_ref.3: type = import_ref Main//extend_generic_base, inst+50, loaded [template = constants.%Derived] // CHECK:STDOUT: %import_ref.4 = import_ref Main//extend_generic_base, inst+80, unloaded // CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { -// CHECK:STDOUT: .Int = %import_ref.12 +// CHECK:STDOUT: .Int = %import_ref.13 // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } @@ -278,9 +278,9 @@ fn H() { // CHECK:STDOUT: %import_ref.6: %.17 = import_ref Main//extend_generic_base, inst+46, loaded [template = %.1] // CHECK:STDOUT: %import_ref.7 = import_ref Main//extend_generic_base, inst+15, unloaded // CHECK:STDOUT: %import_ref.8: @Base.%.1 (%.9) = import_ref Main//extend_generic_base, inst+18, loaded [template = %.2] -// CHECK:STDOUT: %import_ref.9 = import_ref Main//extend_generic_base, inst+51, unloaded -// CHECK:STDOUT: %import_ref.10 = import_ref Main//extend_generic_base, inst+63, unloaded -// CHECK:STDOUT: %import_ref.11: type = import_ref Main//extend_generic_base, inst+54, loaded [template = constants.%Base.3] +// CHECK:STDOUT: %import_ref.10 = import_ref Main//extend_generic_base, inst+51, unloaded +// CHECK:STDOUT: %import_ref.11 = import_ref Main//extend_generic_base, inst+63, unloaded +// CHECK:STDOUT: %import_ref.12: type = import_ref Main//extend_generic_base, inst+54, loaded [template = constants.%Base.3] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -314,9 +314,9 @@ fn H() { // CHECK:STDOUT: // CHECK:STDOUT: class @Derived { // CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = imports.%import_ref.9 -// CHECK:STDOUT: .base = imports.%import_ref.10 -// CHECK:STDOUT: extend imports.%import_ref.11 +// CHECK:STDOUT: .Self = imports.%import_ref.10 +// CHECK:STDOUT: .base = imports.%import_ref.11 +// CHECK:STDOUT: extend imports.%import_ref.12 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @Param { @@ -586,7 +586,7 @@ fn H() { // CHECK:STDOUT: %X.ref: %X.type = name_ref X, file.%X.decl [template = constants.%X.1] // CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc8_9.1 [symbolic = %T.loc8_9.2 (constants.%T)] // CHECK:STDOUT: %X.loc9_17.1: type = class_type @X, @X(constants.%T) [symbolic = %X.loc9_17.2 (constants.%X.3)] -// CHECK:STDOUT: %.loc9_20.1: @C.%.loc9_20.2 (%.5) = base_decl %X.3, element0 [template] +// CHECK:STDOUT: %.loc9_20.1: @C.%.loc9_20.2 (%.5) = base_decl %X.loc9_17.1, element0 [template] // CHECK:STDOUT: %.loc10_1.1: = complete_type_witness %.6 [symbolic = %.loc10_1.3 (constants.%.7)] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -770,9 +770,9 @@ fn H() { // CHECK:STDOUT: } // CHECK:STDOUT: %import_ref.5 = import_ref Main//extend_generic_symbolic_base, inst+15, unloaded // CHECK:STDOUT: %import_ref.6: @X.%G.type (%G.type.1) = import_ref Main//extend_generic_symbolic_base, inst+21, loaded [symbolic = @X.%G (constants.%G.1)] -// CHECK:STDOUT: %import_ref.7 = import_ref Main//extend_generic_symbolic_base, inst+52, unloaded -// CHECK:STDOUT: %import_ref.8 = import_ref Main//extend_generic_symbolic_base, inst+61, unloaded -// CHECK:STDOUT: %import_ref.9: type = import_ref Main//extend_generic_symbolic_base, inst+55, loaded [symbolic = @C.%X (constants.%X.3)] +// CHECK:STDOUT: %import_ref.8 = import_ref Main//extend_generic_symbolic_base, inst+52, unloaded +// CHECK:STDOUT: %import_ref.9 = import_ref Main//extend_generic_symbolic_base, inst+61, unloaded +// CHECK:STDOUT: %import_ref.10: type = import_ref Main//extend_generic_symbolic_base, inst+55, loaded [symbolic = @C.%X (constants.%X.3)] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -801,9 +801,9 @@ fn H() { // CHECK:STDOUT: // CHECK:STDOUT: class { // CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = imports.%import_ref.7 -// CHECK:STDOUT: .base = imports.%import_ref.8 -// CHECK:STDOUT: extend imports.%import_ref.9 +// CHECK:STDOUT: .Self = imports.%import_ref.8 +// CHECK:STDOUT: .base = imports.%import_ref.9 +// CHECK:STDOUT: extend imports.%import_ref.10 // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/generic/init.carbon b/toolchain/check/testdata/class/generic/init.carbon index a2db729276b37..5c2807cf1081d 100644 --- a/toolchain/check/testdata/class/generic/init.carbon +++ b/toolchain/check/testdata/class/generic/init.carbon @@ -332,7 +332,7 @@ fn InitFromAdaptedSpecific(x: i32) -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: class { // CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc4_13.1 [symbolic = %T.loc4_13.2 (constants.%T)] -// CHECK:STDOUT: adapt_decl %T +// CHECK:STDOUT: adapt_decl %T.ref // CHECK:STDOUT: %.loc6_1.1: = complete_type_witness %T [symbolic = %.loc6_1.2 (constants.%.1)] // CHECK:STDOUT: // CHECK:STDOUT: !members: diff --git a/toolchain/check/testdata/class/import_base.carbon b/toolchain/check/testdata/class/import_base.carbon index c3663d2cd2917..5e427c27a0ebe 100644 --- a/toolchain/check/testdata/class/import_base.carbon +++ b/toolchain/check/testdata/class/import_base.carbon @@ -115,7 +115,7 @@ fn Run() { // CHECK:STDOUT: // CHECK:STDOUT: class @Child { // CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base] -// CHECK:STDOUT: %.loc13: %.6 = base_decl %Base, element0 [template] +// CHECK:STDOUT: %.loc13: %.6 = base_decl %Base.ref, element0 [template] // CHECK:STDOUT: %.loc14: = complete_type_witness %.7 [template = constants.%.8] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -167,7 +167,7 @@ fn Run() { // CHECK:STDOUT: %import_ref.1 = import_ref Main//a, inst+3, unloaded // CHECK:STDOUT: %import_ref.2: type = import_ref Main//a, inst+49, loaded [template = constants.%Child] // CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { -// CHECK:STDOUT: .ImplicitAs = %import_ref.11 +// CHECK:STDOUT: .ImplicitAs = %import_ref.12 // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } @@ -176,9 +176,9 @@ fn Run() { // CHECK:STDOUT: %import_ref.5 = import_ref Main//a, inst+19, unloaded // CHECK:STDOUT: %import_ref.6: %.40 = import_ref Main//a, inst+40, loaded [template = %.1] // CHECK:STDOUT: %import_ref.7 = import_ref Main//a, inst+45, unloaded -// CHECK:STDOUT: %import_ref.8 = import_ref Main//a, inst+50, unloaded -// CHECK:STDOUT: %import_ref.9 = import_ref Main//a, inst+54, unloaded -// CHECK:STDOUT: %import_ref.10: type = import_ref Main//a, inst+51, loaded [template = constants.%Base] +// CHECK:STDOUT: %import_ref.9 = import_ref Main//a, inst+50, unloaded +// CHECK:STDOUT: %import_ref.10 = import_ref Main//a, inst+54, unloaded +// CHECK:STDOUT: %import_ref.11: type = import_ref Main//a, inst+51, loaded [template = constants.%Base] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -195,9 +195,9 @@ fn Run() { // CHECK:STDOUT: // CHECK:STDOUT: class @Child { // CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = imports.%import_ref.8 -// CHECK:STDOUT: .base = imports.%import_ref.9 -// CHECK:STDOUT: extend imports.%import_ref.10 +// CHECK:STDOUT: .Self = imports.%import_ref.9 +// CHECK:STDOUT: .base = imports.%import_ref.10 +// CHECK:STDOUT: extend imports.%import_ref.11 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @Base { diff --git a/toolchain/check/testdata/class/inheritance_access.carbon b/toolchain/check/testdata/class/inheritance_access.carbon index 63ebbd3d08ae5..ab7277857d868 100644 --- a/toolchain/check/testdata/class/inheritance_access.carbon +++ b/toolchain/check/testdata/class/inheritance_access.carbon @@ -287,7 +287,7 @@ class B { // CHECK:STDOUT: // CHECK:STDOUT: class @Circle { // CHECK:STDOUT: %Shape.ref: type = name_ref Shape, file.%Shape.decl [template = constants.%Shape] -// CHECK:STDOUT: %.loc10: %.6 = base_decl %Shape, element0 [template] +// CHECK:STDOUT: %.loc10: %.6 = base_decl %Shape.ref, element0 [template] // CHECK:STDOUT: %GetPosition.decl: %GetPosition.type = fn_decl @GetPosition [template = constants.%GetPosition] { // CHECK:STDOUT: %self.patt: %Circle = binding_pattern self // CHECK:STDOUT: %self.param_patt: %Circle = value_param_pattern %self.patt, runtime_param0 @@ -403,7 +403,7 @@ class B { // CHECK:STDOUT: // CHECK:STDOUT: class @B { // CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [template = constants.%A] -// CHECK:STDOUT: %.loc9: %.4 = base_decl %A, element0 [template] +// CHECK:STDOUT: %.loc9: %.4 = base_decl %A.ref, element0 [template] // CHECK:STDOUT: %F.decl: %F.type.2 = fn_decl @F.2 [template = constants.%F.2] { // CHECK:STDOUT: %return.patt: %i32 = return_slot_pattern // CHECK:STDOUT: %return.param_patt: %i32 = out_param_pattern %return.patt, runtime_param0 @@ -426,7 +426,7 @@ class B { // CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B] -// CHECK:STDOUT: %.loc14: %.10 = base_decl %B, element0 [template] +// CHECK:STDOUT: %.loc14: %.10 = base_decl %B.ref, element0 [template] // CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [template = constants.%G] { // CHECK:STDOUT: %self.patt: %C = binding_pattern self // CHECK:STDOUT: %self.param_patt: %C = value_param_pattern %self.patt, runtime_param0 @@ -550,7 +550,7 @@ class B { // CHECK:STDOUT: // CHECK:STDOUT: class @B { // CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [template = constants.%A] -// CHECK:STDOUT: %.loc12: %.29 = base_decl %A, element0 [template] +// CHECK:STDOUT: %.loc12: %.29 = base_decl %A.ref, element0 [template] // CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [template = constants.%G] { // CHECK:STDOUT: %return.patt: %i32 = return_slot_pattern // CHECK:STDOUT: %return.param_patt: %i32 = out_param_pattern %return.patt, runtime_param0 @@ -665,7 +665,7 @@ class B { // CHECK:STDOUT: // CHECK:STDOUT: class @Square { // CHECK:STDOUT: %Shape.ref: type = name_ref Shape, file.%Shape.decl [template = constants.%Shape] -// CHECK:STDOUT: %.loc9: %.6 = base_decl %Shape, element0 [template] +// CHECK:STDOUT: %.loc9: %.6 = base_decl %Shape.ref, element0 [template] // CHECK:STDOUT: %GetPosition.decl: %GetPosition.type = fn_decl @GetPosition [template = constants.%GetPosition] { // CHECK:STDOUT: %self.patt: %Square = binding_pattern self // CHECK:STDOUT: %self.param_patt: %Square = value_param_pattern %self.patt, runtime_param0 @@ -849,7 +849,7 @@ class B { // CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B] -// CHECK:STDOUT: %.loc9: %.4 = base_decl %B, element0 [template] +// CHECK:STDOUT: %.loc9: %.4 = base_decl %B.ref, element0 [template] // CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [template = constants.%G] {} {} // CHECK:STDOUT: %.loc18: = complete_type_witness %.5 [template = constants.%.6] // CHECK:STDOUT: @@ -918,7 +918,7 @@ class B { // CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B] -// CHECK:STDOUT: %.loc9: %.4 = base_decl %B, element0 [template] +// CHECK:STDOUT: %.loc9: %.4 = base_decl %B.ref, element0 [template] // CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [template = constants.%G] {} {} // CHECK:STDOUT: %.loc11: = complete_type_witness %.5 [template = constants.%.6] // CHECK:STDOUT: @@ -1157,7 +1157,7 @@ class B { // CHECK:STDOUT: // CHECK:STDOUT: class @B { // CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [template = constants.%A] -// CHECK:STDOUT: %.loc9: %.6 = base_decl %A, element0 [template] +// CHECK:STDOUT: %.loc9: %.6 = base_decl %A.ref, element0 [template] // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] { // CHECK:STDOUT: %self.patt: %B = binding_pattern self // CHECK:STDOUT: %self.param_patt: %B = value_param_pattern %self.patt, runtime_param0 @@ -1236,7 +1236,7 @@ class B { // CHECK:STDOUT: // CHECK:STDOUT: class @B { // CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [template = constants.%A] -// CHECK:STDOUT: %.loc9: %.6 = base_decl %A, element0 [template] +// CHECK:STDOUT: %.loc9: %.6 = base_decl %A.ref, element0 [template] // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] { // CHECK:STDOUT: %self.patt: %B = binding_pattern self // CHECK:STDOUT: %self.param_patt: %B = value_param_pattern %self.patt, runtime_param0 diff --git a/toolchain/check/testdata/class/init_adapt.carbon b/toolchain/check/testdata/class/init_adapt.carbon index 783456bc5bdca..1d78c5944f404 100644 --- a/toolchain/check/testdata/class/init_adapt.carbon +++ b/toolchain/check/testdata/class/init_adapt.carbon @@ -103,21 +103,20 @@ var e: C = MakeAdaptC(); // CHECK:STDOUT: %.3: type = struct_type {.a: %i32, .b: %i32} [template] // CHECK:STDOUT: %.4: = complete_type_witness %.3 [template] // CHECK:STDOUT: %AdaptC: type = class_type @AdaptC [template] -// CHECK:STDOUT: %.6: = complete_type_witness %C [template] -// CHECK:STDOUT: %.7: Core.IntLiteral = int_value 1 [template] -// CHECK:STDOUT: %.8: Core.IntLiteral = int_value 2 [template] -// CHECK:STDOUT: %.9: type = struct_type {.a: Core.IntLiteral, .b: Core.IntLiteral} [template] +// CHECK:STDOUT: %.6: Core.IntLiteral = int_value 1 [template] +// CHECK:STDOUT: %.7: Core.IntLiteral = int_value 2 [template] +// CHECK:STDOUT: %.8: type = struct_type {.a: Core.IntLiteral, .b: Core.IntLiteral} [template] // CHECK:STDOUT: %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(%i32) [template] // CHECK:STDOUT: %Convert.type.14: type = fn_type @Convert.2, @impl.1(%.1) [template] // CHECK:STDOUT: %Convert.14: %Convert.type.14 = struct_value () [template] -// CHECK:STDOUT: %.29: = interface_witness (%Convert.14) [template] -// CHECK:STDOUT: %.30: = bound_method %.7, %Convert.14 [template] -// CHECK:STDOUT: %.31: = specific_function %.30, @Convert.2(%.1) [template] -// CHECK:STDOUT: %.32: %i32 = int_value 1 [template] -// CHECK:STDOUT: %.33: = bound_method %.8, %Convert.14 [template] -// CHECK:STDOUT: %.34: = specific_function %.33, @Convert.2(%.1) [template] -// CHECK:STDOUT: %.35: %i32 = int_value 2 [template] -// CHECK:STDOUT: %struct: %C = struct_value (%.32, %.35) [template] +// CHECK:STDOUT: %.28: = interface_witness (%Convert.14) [template] +// CHECK:STDOUT: %.29: = bound_method %.6, %Convert.14 [template] +// CHECK:STDOUT: %.30: = specific_function %.29, @Convert.2(%.1) [template] +// CHECK:STDOUT: %.31: %i32 = int_value 1 [template] +// CHECK:STDOUT: %.32: = bound_method %.7, %Convert.14 [template] +// CHECK:STDOUT: %.33: = specific_function %.32, @Convert.2(%.1) [template] +// CHECK:STDOUT: %.34: %i32 = int_value 2 [template] +// CHECK:STDOUT: %struct: %C = struct_value (%.31, %.34) [template] // CHECK:STDOUT: %MakeC.type: type = fn_type @MakeC [template] // CHECK:STDOUT: %MakeC: %MakeC.type = struct_value () [template] // CHECK:STDOUT: %MakeAdaptC.type: type = fn_type @MakeAdaptC [template] @@ -197,8 +196,8 @@ var e: C = MakeAdaptC(); // CHECK:STDOUT: // CHECK:STDOUT: class @AdaptC { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [template = constants.%C] -// CHECK:STDOUT: adapt_decl %C -// CHECK:STDOUT: %.loc11: = complete_type_witness %C [template = constants.%.6] +// CHECK:STDOUT: adapt_decl %C.ref +// CHECK:STDOUT: %.loc11: = complete_type_witness %.3 [template = constants.%.4] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%AdaptC @@ -210,24 +209,24 @@ var e: C = MakeAdaptC(); // CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %.loc13_18: Core.IntLiteral = int_value 1 [template = constants.%.7] -// CHECK:STDOUT: %.loc13_26: Core.IntLiteral = int_value 2 [template = constants.%.8] -// CHECK:STDOUT: %.loc13_27.1: %.9 = struct_literal (%.loc13_18, %.loc13_26) -// CHECK:STDOUT: %.loc13_27.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.14] -// CHECK:STDOUT: %.loc13_27.3: = bound_method %.loc13_18, %.loc13_27.2 [template = constants.%.30] -// CHECK:STDOUT: %.loc13_27.4: = specific_function %.loc13_27.3, @Convert.2(constants.%.1) [template = constants.%.31] -// CHECK:STDOUT: %int.convert_checked.loc13_27.1: init %i32 = call %.loc13_27.4(%.loc13_18) [template = constants.%.32] -// CHECK:STDOUT: %.loc13_27.5: init %i32 = converted %.loc13_18, %int.convert_checked.loc13_27.1 [template = constants.%.32] +// CHECK:STDOUT: %.loc13_18: Core.IntLiteral = int_value 1 [template = constants.%.6] +// CHECK:STDOUT: %.loc13_26: Core.IntLiteral = int_value 2 [template = constants.%.7] +// CHECK:STDOUT: %.loc13_27.1: %.8 = struct_literal (%.loc13_18, %.loc13_26) +// CHECK:STDOUT: %.loc13_27.2: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.14] +// CHECK:STDOUT: %.loc13_27.3: = bound_method %.loc13_18, %.loc13_27.2 [template = constants.%.29] +// CHECK:STDOUT: %.loc13_27.4: = specific_function %.loc13_27.3, @Convert.2(constants.%.1) [template = constants.%.30] +// CHECK:STDOUT: %int.convert_checked.loc13_27.1: init %i32 = call %.loc13_27.4(%.loc13_18) [template = constants.%.31] +// CHECK:STDOUT: %.loc13_27.5: init %i32 = converted %.loc13_18, %int.convert_checked.loc13_27.1 [template = constants.%.31] // CHECK:STDOUT: %.loc13_27.6: ref %C = temporary_storage // CHECK:STDOUT: %.loc13_27.7: ref %i32 = class_element_access %.loc13_27.6, element0 -// CHECK:STDOUT: %.loc13_27.8: init %i32 = initialize_from %.loc13_27.5 to %.loc13_27.7 [template = constants.%.32] -// CHECK:STDOUT: %.loc13_27.9: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.14] -// CHECK:STDOUT: %.loc13_27.10: = bound_method %.loc13_26, %.loc13_27.9 [template = constants.%.33] -// CHECK:STDOUT: %.loc13_27.11: = specific_function %.loc13_27.10, @Convert.2(constants.%.1) [template = constants.%.34] -// CHECK:STDOUT: %int.convert_checked.loc13_27.2: init %i32 = call %.loc13_27.11(%.loc13_26) [template = constants.%.35] -// CHECK:STDOUT: %.loc13_27.12: init %i32 = converted %.loc13_26, %int.convert_checked.loc13_27.2 [template = constants.%.35] +// CHECK:STDOUT: %.loc13_27.8: init %i32 = initialize_from %.loc13_27.5 to %.loc13_27.7 [template = constants.%.31] +// CHECK:STDOUT: %.loc13_27.9: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.14] +// CHECK:STDOUT: %.loc13_27.10: = bound_method %.loc13_26, %.loc13_27.9 [template = constants.%.32] +// CHECK:STDOUT: %.loc13_27.11: = specific_function %.loc13_27.10, @Convert.2(constants.%.1) [template = constants.%.33] +// CHECK:STDOUT: %int.convert_checked.loc13_27.2: init %i32 = call %.loc13_27.11(%.loc13_26) [template = constants.%.34] +// CHECK:STDOUT: %.loc13_27.12: init %i32 = converted %.loc13_26, %int.convert_checked.loc13_27.2 [template = constants.%.34] // CHECK:STDOUT: %.loc13_27.13: ref %i32 = class_element_access %.loc13_27.6, element1 -// CHECK:STDOUT: %.loc13_27.14: init %i32 = initialize_from %.loc13_27.12 to %.loc13_27.13 [template = constants.%.35] +// CHECK:STDOUT: %.loc13_27.14: init %i32 = initialize_from %.loc13_27.12 to %.loc13_27.13 [template = constants.%.34] // CHECK:STDOUT: %.loc13_27.15: init %C = class_init (%.loc13_27.8, %.loc13_27.14), %.loc13_27.6 [template = constants.%struct] // CHECK:STDOUT: %.loc13_27.16: ref %C = temporary %.loc13_27.6, %.loc13_27.15 // CHECK:STDOUT: %.loc13_28.1: ref %C = converted %.loc13_27.1, %.loc13_27.16 @@ -272,21 +271,20 @@ var e: C = MakeAdaptC(); // CHECK:STDOUT: %.3: type = struct_type {.a: %i32, .b: %i32} [template] // CHECK:STDOUT: %.4: = complete_type_witness %.3 [template] // CHECK:STDOUT: %AdaptC: type = class_type @AdaptC [template] -// CHECK:STDOUT: %.6: = complete_type_witness %C [template] -// CHECK:STDOUT: %.7: Core.IntLiteral = int_value 1 [template] -// CHECK:STDOUT: %.8: Core.IntLiteral = int_value 2 [template] -// CHECK:STDOUT: %.9: type = struct_type {.a: Core.IntLiteral, .b: Core.IntLiteral} [template] +// CHECK:STDOUT: %.6: Core.IntLiteral = int_value 1 [template] +// CHECK:STDOUT: %.7: Core.IntLiteral = int_value 2 [template] +// CHECK:STDOUT: %.8: type = struct_type {.a: Core.IntLiteral, .b: Core.IntLiteral} [template] // CHECK:STDOUT: %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(%i32) [template] // CHECK:STDOUT: %Convert.type.14: type = fn_type @Convert.2, @impl.1(%.1) [template] // CHECK:STDOUT: %Convert.14: %Convert.type.14 = struct_value () [template] -// CHECK:STDOUT: %.29: = interface_witness (%Convert.14) [template] -// CHECK:STDOUT: %.30: = bound_method %.7, %Convert.14 [template] -// CHECK:STDOUT: %.31: = specific_function %.30, @Convert.2(%.1) [template] -// CHECK:STDOUT: %.32: %i32 = int_value 1 [template] -// CHECK:STDOUT: %.33: = bound_method %.8, %Convert.14 [template] -// CHECK:STDOUT: %.34: = specific_function %.33, @Convert.2(%.1) [template] -// CHECK:STDOUT: %.35: %i32 = int_value 2 [template] -// CHECK:STDOUT: %struct: %C = struct_value (%.32, %.35) [template] +// CHECK:STDOUT: %.28: = interface_witness (%Convert.14) [template] +// CHECK:STDOUT: %.29: = bound_method %.6, %Convert.14 [template] +// CHECK:STDOUT: %.30: = specific_function %.29, @Convert.2(%.1) [template] +// CHECK:STDOUT: %.31: %i32 = int_value 1 [template] +// CHECK:STDOUT: %.32: = bound_method %.7, %Convert.14 [template] +// CHECK:STDOUT: %.33: = specific_function %.32, @Convert.2(%.1) [template] +// CHECK:STDOUT: %.34: %i32 = int_value 2 [template] +// CHECK:STDOUT: %struct: %C = struct_value (%.31, %.34) [template] // CHECK:STDOUT: %MakeC.type: type = fn_type @MakeC [template] // CHECK:STDOUT: %MakeC: %MakeC.type = struct_value () [template] // CHECK:STDOUT: %MakeAdaptC.type: type = fn_type @MakeAdaptC [template] @@ -366,8 +364,8 @@ var e: C = MakeAdaptC(); // CHECK:STDOUT: // CHECK:STDOUT: class @AdaptC { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [template = constants.%C] -// CHECK:STDOUT: adapt_decl %C -// CHECK:STDOUT: %.loc11: = complete_type_witness %C [template = constants.%.6] +// CHECK:STDOUT: adapt_decl %C.ref +// CHECK:STDOUT: %.loc11: = complete_type_witness %.3 [template = constants.%.4] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%AdaptC @@ -379,24 +377,24 @@ var e: C = MakeAdaptC(); // CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %.loc13_18: Core.IntLiteral = int_value 1 [template = constants.%.7] -// CHECK:STDOUT: %.loc13_26: Core.IntLiteral = int_value 2 [template = constants.%.8] -// CHECK:STDOUT: %.loc13_27.1: %.9 = struct_literal (%.loc13_18, %.loc13_26) -// CHECK:STDOUT: %.loc13_27.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.14] -// CHECK:STDOUT: %.loc13_27.3: = bound_method %.loc13_18, %.loc13_27.2 [template = constants.%.30] -// CHECK:STDOUT: %.loc13_27.4: = specific_function %.loc13_27.3, @Convert.2(constants.%.1) [template = constants.%.31] -// CHECK:STDOUT: %int.convert_checked.loc13_27.1: init %i32 = call %.loc13_27.4(%.loc13_18) [template = constants.%.32] -// CHECK:STDOUT: %.loc13_27.5: init %i32 = converted %.loc13_18, %int.convert_checked.loc13_27.1 [template = constants.%.32] +// CHECK:STDOUT: %.loc13_18: Core.IntLiteral = int_value 1 [template = constants.%.6] +// CHECK:STDOUT: %.loc13_26: Core.IntLiteral = int_value 2 [template = constants.%.7] +// CHECK:STDOUT: %.loc13_27.1: %.8 = struct_literal (%.loc13_18, %.loc13_26) +// CHECK:STDOUT: %.loc13_27.2: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.14] +// CHECK:STDOUT: %.loc13_27.3: = bound_method %.loc13_18, %.loc13_27.2 [template = constants.%.29] +// CHECK:STDOUT: %.loc13_27.4: = specific_function %.loc13_27.3, @Convert.2(constants.%.1) [template = constants.%.30] +// CHECK:STDOUT: %int.convert_checked.loc13_27.1: init %i32 = call %.loc13_27.4(%.loc13_18) [template = constants.%.31] +// CHECK:STDOUT: %.loc13_27.5: init %i32 = converted %.loc13_18, %int.convert_checked.loc13_27.1 [template = constants.%.31] // CHECK:STDOUT: %.loc13_27.6: ref %C = temporary_storage // CHECK:STDOUT: %.loc13_27.7: ref %i32 = class_element_access %.loc13_27.6, element0 -// CHECK:STDOUT: %.loc13_27.8: init %i32 = initialize_from %.loc13_27.5 to %.loc13_27.7 [template = constants.%.32] -// CHECK:STDOUT: %.loc13_27.9: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.14] -// CHECK:STDOUT: %.loc13_27.10: = bound_method %.loc13_26, %.loc13_27.9 [template = constants.%.33] -// CHECK:STDOUT: %.loc13_27.11: = specific_function %.loc13_27.10, @Convert.2(constants.%.1) [template = constants.%.34] -// CHECK:STDOUT: %int.convert_checked.loc13_27.2: init %i32 = call %.loc13_27.11(%.loc13_26) [template = constants.%.35] -// CHECK:STDOUT: %.loc13_27.12: init %i32 = converted %.loc13_26, %int.convert_checked.loc13_27.2 [template = constants.%.35] +// CHECK:STDOUT: %.loc13_27.8: init %i32 = initialize_from %.loc13_27.5 to %.loc13_27.7 [template = constants.%.31] +// CHECK:STDOUT: %.loc13_27.9: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.14] +// CHECK:STDOUT: %.loc13_27.10: = bound_method %.loc13_26, %.loc13_27.9 [template = constants.%.32] +// CHECK:STDOUT: %.loc13_27.11: = specific_function %.loc13_27.10, @Convert.2(constants.%.1) [template = constants.%.33] +// CHECK:STDOUT: %int.convert_checked.loc13_27.2: init %i32 = call %.loc13_27.11(%.loc13_26) [template = constants.%.34] +// CHECK:STDOUT: %.loc13_27.12: init %i32 = converted %.loc13_26, %int.convert_checked.loc13_27.2 [template = constants.%.34] // CHECK:STDOUT: %.loc13_27.13: ref %i32 = class_element_access %.loc13_27.6, element1 -// CHECK:STDOUT: %.loc13_27.14: init %i32 = initialize_from %.loc13_27.12 to %.loc13_27.13 [template = constants.%.35] +// CHECK:STDOUT: %.loc13_27.14: init %i32 = initialize_from %.loc13_27.12 to %.loc13_27.13 [template = constants.%.34] // CHECK:STDOUT: %.loc13_27.15: init %C = class_init (%.loc13_27.8, %.loc13_27.14), %.loc13_27.6 [template = constants.%struct] // CHECK:STDOUT: %.loc13_27.16: ref %C = temporary %.loc13_27.6, %.loc13_27.15 // CHECK:STDOUT: %.loc13_28.1: ref %C = converted %.loc13_27.1, %.loc13_27.16 diff --git a/toolchain/check/testdata/class/self_conversion.carbon b/toolchain/check/testdata/class/self_conversion.carbon index da466a408be92..76925c5802b37 100644 --- a/toolchain/check/testdata/class/self_conversion.carbon +++ b/toolchain/check/testdata/class/self_conversion.carbon @@ -145,7 +145,7 @@ fn Call(p: Derived*) -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: class @Derived { // CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base] -// CHECK:STDOUT: %.loc16: %.6 = base_decl %Base, element0 [template] +// CHECK:STDOUT: %.loc16: %.6 = base_decl %Base.ref, element0 [template] // CHECK:STDOUT: %SelfBase.decl: %SelfBase.type = fn_decl @SelfBase [template = constants.%SelfBase] { // CHECK:STDOUT: %self.patt: %Base = binding_pattern self // CHECK:STDOUT: %self.param_patt: %Base = value_param_pattern %self.patt, runtime_param0 diff --git a/toolchain/check/testdata/class/virtual_modifiers.carbon b/toolchain/check/testdata/class/virtual_modifiers.carbon index 5c0cfaa17aea2..58a401fac23a5 100644 --- a/toolchain/check/testdata/class/virtual_modifiers.carbon +++ b/toolchain/check/testdata/class/virtual_modifiers.carbon @@ -161,7 +161,7 @@ fn F() { // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] {} {} // CHECK:STDOUT: %Modifiers.ref: = name_ref Modifiers, imports.%Modifiers [template = imports.%Modifiers] // CHECK:STDOUT: %Base.ref: type = name_ref Base, imports.%import_ref.1 [template = constants.%Base] -// CHECK:STDOUT: %.loc8: %.5 = base_decl %Base, element0 [template] +// CHECK:STDOUT: %.loc8: %.5 = base_decl %Base.ref, element0 [template] // CHECK:STDOUT: %.loc9: = complete_type_witness %.6 [template = constants.%.7] // CHECK:STDOUT: // CHECK:STDOUT: !members: diff --git a/toolchain/check/testdata/impl/multiple_extend.carbon b/toolchain/check/testdata/impl/multiple_extend.carbon index 3216e91262df9..8cea083ec5cb6 100644 --- a/toolchain/check/testdata/impl/multiple_extend.carbon +++ b/toolchain/check/testdata/impl/multiple_extend.carbon @@ -560,7 +560,7 @@ fn P(o: O) { // CHECK:STDOUT: // CHECK:STDOUT: class @E { // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B] -// CHECK:STDOUT: %.loc13: %.6 = base_decl %B, element0 [template] +// CHECK:STDOUT: %.loc13: %.6 = base_decl %B.ref, element0 [template] // CHECK:STDOUT: impl_decl @impl [template] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%E [template = constants.%E] // CHECK:STDOUT: %HasI.ref: type = name_ref HasI, file.%HasI.decl [template = constants.%HasI.type] @@ -697,7 +697,7 @@ fn P(o: O) { // CHECK:STDOUT: // CHECK:STDOUT: class @L { // CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base] -// CHECK:STDOUT: %.loc13: %.6 = base_decl %Base, element0 [template] +// CHECK:STDOUT: %.loc13: %.6 = base_decl %Base.ref, element0 [template] // CHECK:STDOUT: impl_decl @impl [template] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%L [template = constants.%L] // CHECK:STDOUT: %HasK.ref: type = name_ref HasK, file.%HasK.decl [template = constants.%HasK.type] @@ -858,7 +858,7 @@ fn P(o: O) { // CHECK:STDOUT: // CHECK:STDOUT: class @O { // CHECK:STDOUT: %NBase.ref: type = name_ref NBase, file.%NBase.decl [template = constants.%NBase] -// CHECK:STDOUT: %.loc17: %.8 = base_decl %NBase, element0 [template] +// CHECK:STDOUT: %.loc17: %.8 = base_decl %NBase.ref, element0 [template] // CHECK:STDOUT: impl_decl @impl.1 [template] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%O [template = constants.%O] // CHECK:STDOUT: %HasN1.ref: type = name_ref HasN1, file.%HasN1.decl [template = constants.%HasN1.type] diff --git a/toolchain/lower/handle_aggregates.cpp b/toolchain/lower/handle_aggregates.cpp index 45d710cf984c0..c74ae8eb77b57 100644 --- a/toolchain/lower/handle_aggregates.cpp +++ b/toolchain/lower/handle_aggregates.cpp @@ -102,11 +102,8 @@ auto HandleInst(FunctionContext& context, SemIR::InstId inst_id, SemIR::ClassElementAccess inst) -> void { // Find the class that we're performing access into. auto class_type_id = context.sem_ir().insts().Get(inst.base_id).type_id(); - auto class_type = - context.sem_ir().types().GetAs(class_type_id); - const auto& class_info = context.sem_ir().classes().Get(class_type.class_id); SemIR::TypeId object_repr_id = - class_info.GetObjectRepr(context.sem_ir(), class_type.specific_id); + context.sem_ir().types().GetObjectRepr(class_type_id); // Translate the class field access into a struct access on the object // representation. diff --git a/toolchain/sem_ir/class.cpp b/toolchain/sem_ir/class.cpp index 30400a705bf02..6602e785080ad 100644 --- a/toolchain/sem_ir/class.cpp +++ b/toolchain/sem_ir/class.cpp @@ -10,6 +10,33 @@ namespace Carbon::SemIR { +auto Class::GetAdaptedType(const File& file, SpecificId specific_id) const + -> TypeId { + if (!adapt_id.is_valid()) { + return TypeId::Invalid; + } + if (base_id == SemIR::InstId::BuiltinErrorInst) { + return TypeId::Error; + } + return TypeId::ForTypeConstant(GetConstantValueInSpecific( + file, specific_id, + file.insts().GetAs(adapt_id).adapted_type_inst_id)); +} + +auto Class::GetBaseType(const File& file, SpecificId specific_id) const + -> TypeId { + if (!base_id.is_valid()) { + return TypeId::Invalid; + } + if (base_id == SemIR::InstId::BuiltinErrorInst) { + return TypeId::Error; + } + CARBON_CHECK(base_id.index >= 0); + return TypeId::ForTypeConstant(GetConstantValueInSpecific( + file, specific_id, + file.insts().GetAs(base_id).base_type_inst_id)); +} + auto Class::GetObjectRepr(const File& file, SpecificId specific_id) const -> TypeId { if (!complete_type_witness_id.is_valid()) { diff --git a/toolchain/sem_ir/class.h b/toolchain/sem_ir/class.h index 12c66629bfcdd..6eeec7dcaf517 100644 --- a/toolchain/sem_ir/class.h +++ b/toolchain/sem_ir/class.h @@ -77,6 +77,14 @@ struct Class : public EntityWithParamsBase, return complete_type_witness_id.is_valid(); } + // Gets the type that this class type adapts. Returns Invalid if there is no + // such type, or if the class is not yet defined. + auto GetAdaptedType(const File& file, SpecificId specific_id) const -> TypeId; + + // Gets the base class for this class type. Returns Invalid if there is no + // such type, or if the class is not yet defined. + auto GetBaseType(const File& file, SpecificId specific_id) const -> TypeId; + // Gets the object representation for this class. Returns Invalid if the class // is not yet defined. auto GetObjectRepr(const File& file, SpecificId specific_id) const -> TypeId; diff --git a/toolchain/sem_ir/type.cpp b/toolchain/sem_ir/type.cpp index 56317137c5b4c..7bfc613acd4a5 100644 --- a/toolchain/sem_ir/type.cpp +++ b/toolchain/sem_ir/type.cpp @@ -17,6 +17,7 @@ auto TypeStore::GetAsInst(TypeId type_id) const -> Inst { } auto TypeStore::GetObjectRepr(TypeId type_id) const -> TypeId { + type_id = GetUnqualifiedType(type_id); auto class_type = TryGetAs(type_id); if (!class_type) { return type_id; @@ -28,6 +29,13 @@ auto TypeStore::GetObjectRepr(TypeId type_id) const -> TypeId { return class_info.GetObjectRepr(*file_, class_type->specific_id); } +auto TypeStore::GetUnqualifiedType(TypeId type_id) const -> TypeId { + if (auto const_type = TryGetAs(type_id)) { + return const_type->inner_id; + } + return type_id; +} + auto TypeStore::IsSignedInt(TypeId int_type_id) const -> bool { auto object_repr_id = GetObjectRepr(int_type_id); if (!object_repr_id.is_valid()) { diff --git a/toolchain/sem_ir/type.h b/toolchain/sem_ir/type.h index 72831833351a4..39cdbc84e758d 100644 --- a/toolchain/sem_ir/type.h +++ b/toolchain/sem_ir/type.h @@ -98,6 +98,9 @@ class TypeStore : public Yaml::Printable { return complete_type_info_.Contains(type_id); } + // Removes any top-level `const` qualifiers from a type. + auto GetUnqualifiedType(TypeId type_id) const -> TypeId; + // Determines whether the given type is a signed integer type. This includes // the case where the type is `Core.IntLiteral` or a class type whose object // representation is a signed integer type. diff --git a/toolchain/sem_ir/typed_insts.h b/toolchain/sem_ir/typed_insts.h index fab9f5653c472..e9c32f430e22f 100644 --- a/toolchain/sem_ir/typed_insts.h +++ b/toolchain/sem_ir/typed_insts.h @@ -65,7 +65,7 @@ struct AdaptDecl { {.ir_name = "adapt_decl", .is_lowered = false}); // No type_id; this is not a value. - TypeId adapted_type_id; + InstId adapted_type_inst_id; }; // Takes the address of a reference expression, such as for the `&` address-of @@ -228,7 +228,7 @@ struct BaseDecl { {.ir_name = "base_decl", .constant_kind = InstConstantKind::Always}); TypeId type_id; - TypeId base_type_id; + InstId base_type_inst_id; ElementIndex index; }; From a066c413f8ce799c2aba8791317e6a936aee85fb Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Thu, 21 Nov 2024 19:22:41 +0000 Subject: [PATCH 03/11] Support for generic adapters. --- toolchain/check/eval.cpp | 2 +- toolchain/check/import_ref.cpp | 27 +++++++- .../testdata/as/adapter_conversion.carbon | 16 ++--- toolchain/check/testdata/class/adapt.carbon | 6 +- .../check/testdata/class/extend_adapt.carbon | 12 ++-- .../check/testdata/class/fail_abstract.carbon | 2 +- .../testdata/class/fail_adapt_bad_decl.carbon | 8 +-- .../testdata/class/fail_adapt_bad_type.carbon | 2 +- .../class/fail_adapt_modifiers.carbon | 10 +-- .../class/fail_adapt_with_base.carbon | 2 +- .../class/fail_adapt_with_subobjects.carbon | 8 +-- .../check/testdata/class/generic/init.carbon | 2 +- .../check/testdata/class/init_adapt.carbon | 4 +- toolchain/lower/constant.cpp | 61 ++++++++----------- toolchain/sem_ir/typed_insts.h | 6 +- 15 files changed, 91 insertions(+), 77 deletions(-) diff --git a/toolchain/check/eval.cpp b/toolchain/check/eval.cpp index 6ae645d8cd44d..4cf12359dabb6 100644 --- a/toolchain/check/eval.cpp +++ b/toolchain/check/eval.cpp @@ -1493,6 +1493,7 @@ static auto TryEvalInstInContext(EvalContext& eval_context, // TODO: This doesn't properly handle redeclarations. Consider adding a // corresponding `Value` inst for each of these cases, or returning the // first declaration. + case SemIR::AdaptDecl::Kind: case SemIR::AssociatedConstantDecl::Kind: case SemIR::BaseDecl::Kind: case SemIR::FieldDecl::Kind: @@ -1671,7 +1672,6 @@ static auto TryEvalInstInContext(EvalContext& eval_context, } // These cases are either not expressions or not constant. - case SemIR::AdaptDecl::Kind: case SemIR::AddrPattern::Kind: case SemIR::Assign::Kind: case SemIR::BindName::Kind: diff --git a/toolchain/check/import_ref.cpp b/toolchain/check/import_ref.cpp index 9356a2f591f14..bd2c443977a41 100644 --- a/toolchain/check/import_ref.cpp +++ b/toolchain/check/import_ref.cpp @@ -1163,6 +1163,9 @@ class ImportRefResolver { auto untyped_inst = import_ir_.insts().Get(inst_id); CARBON_KIND_SWITCH(untyped_inst) { + case CARBON_KIND(SemIR::AdaptDecl inst): { + return TryResolveTypedInst(inst, inst_id); + } case CARBON_KIND(SemIR::AssociatedEntity inst): { return TryResolveTypedInst(inst); } @@ -1323,6 +1326,27 @@ class ImportRefResolver { return ResolveAsUntyped(inst); } + auto TryResolveTypedInst(SemIR::AdaptDecl inst, SemIR::InstId import_inst_id) + -> ResolveResult { + auto adapted_type_const_id = GetLocalConstantId( + import_ir_.constant_values().Get(inst.adapted_type_inst_id)); + if (HasNewWork()) { + return Retry(); + } + + auto adapted_type_inst_id = AddLoadedImportRef( + context_, + {.ir_id = import_ir_id_, .inst_id = inst.adapted_type_inst_id}, + SemIR::TypeId::TypeType, adapted_type_const_id); + + // Create a corresponding instruction to represent the declaration. + auto inst_id = context_.AddInstInNoBlock( + context_.MakeImportedLocAndInst( + AddImportIRInst(import_inst_id), + {.adapted_type_inst_id = adapted_type_inst_id})); + return ResolveAsConstant(context_.constant_values().Get(inst_id)); + } + auto TryResolveTypedInst(SemIR::AssociatedEntity inst) -> ResolveResult { auto type_const_id = GetLocalConstantId(inst.type_id); if (HasNewWork()) { @@ -1369,8 +1393,7 @@ class ImportRefResolver { context_, {.ir_id = import_ir_id_, .inst_id = inst.base_type_inst_id}, SemIR::TypeId::TypeType, base_type_const_id); - // Import the instruction in order to update contained base_type_id and - // track the import location. + // Create a corresponding instruction to represent the declaration. auto inst_id = context_.AddInstInNoBlock( context_.MakeImportedLocAndInst( AddImportIRInst(import_inst_id), diff --git a/toolchain/check/testdata/as/adapter_conversion.carbon b/toolchain/check/testdata/as/adapter_conversion.carbon index 28529f89374f6..d1be6dc8c6f6b 100644 --- a/toolchain/check/testdata/as/adapter_conversion.carbon +++ b/toolchain/check/testdata/as/adapter_conversion.carbon @@ -201,7 +201,7 @@ var b: B = {.x = 1} as B; // CHECK:STDOUT: // CHECK:STDOUT: class @B { // CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [template = constants.%A] -// CHECK:STDOUT: adapt_decl %A.ref +// CHECK:STDOUT: adapt_decl %A.ref [template] // CHECK:STDOUT: %.loc15: = complete_type_witness %.3 [template = constants.%.4] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -328,7 +328,7 @@ var b: B = {.x = 1} as B; // CHECK:STDOUT: %int.make_type_signed: init type = call constants.%Int(%.loc5_9) [template = constants.%i32] // CHECK:STDOUT: %.loc5_12.1: type = value_of_initializer %int.make_type_signed [template = constants.%i32] // CHECK:STDOUT: %.loc5_12.2: type = converted %int.make_type_signed, %.loc5_12.1 [template = constants.%i32] -// CHECK:STDOUT: adapt_decl %.loc5_12.2 +// CHECK:STDOUT: adapt_decl %.loc5_12.2 [template] // CHECK:STDOUT: %.loc6: = complete_type_witness %i32 [template = constants.%.2] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -402,7 +402,7 @@ var b: B = {.x = 1} as B; // CHECK:STDOUT: class @A { // CHECK:STDOUT: %.loc4_18: %.1 = struct_literal () // CHECK:STDOUT: %.loc4_19: type = converted %.loc4_18, constants.%.1 [template = constants.%.1] -// CHECK:STDOUT: adapt_decl %.loc4_19 +// CHECK:STDOUT: adapt_decl %.loc4_19 [template] // CHECK:STDOUT: %.loc4_21: = complete_type_witness %.1 [template = constants.%.2] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -411,7 +411,7 @@ var b: B = {.x = 1} as B; // CHECK:STDOUT: // CHECK:STDOUT: class @B { // CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [template = constants.%A] -// CHECK:STDOUT: adapt_decl %A.ref +// CHECK:STDOUT: adapt_decl %A.ref [template] // CHECK:STDOUT: %.loc5: = complete_type_witness %.1 [template = constants.%.2] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -420,7 +420,7 @@ var b: B = {.x = 1} as B; // CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B] -// CHECK:STDOUT: adapt_decl %B.ref +// CHECK:STDOUT: adapt_decl %B.ref [template] // CHECK:STDOUT: %.loc6: = complete_type_witness %.1 [template = constants.%.2] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -429,7 +429,7 @@ var b: B = {.x = 1} as B; // CHECK:STDOUT: // CHECK:STDOUT: class @D { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [template = constants.%C] -// CHECK:STDOUT: adapt_decl %C.ref +// CHECK:STDOUT: adapt_decl %C.ref [template] // CHECK:STDOUT: %.loc7: = complete_type_witness %.1 [template = constants.%.2] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -522,7 +522,7 @@ var b: B = {.x = 1} as B; // CHECK:STDOUT: // CHECK:STDOUT: class @B { // CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [template = constants.%A] -// CHECK:STDOUT: adapt_decl %A.ref +// CHECK:STDOUT: adapt_decl %A.ref [template] // CHECK:STDOUT: %.loc11: = complete_type_witness %.3 [template = constants.%.4] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -643,7 +643,7 @@ var b: B = {.x = 1} as B; // CHECK:STDOUT: // CHECK:STDOUT: class @B { // CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [template = constants.%A] -// CHECK:STDOUT: adapt_decl %A.ref +// CHECK:STDOUT: adapt_decl %A.ref [template] // CHECK:STDOUT: %.loc10: = complete_type_witness %.3 [template = constants.%.4] // CHECK:STDOUT: // CHECK:STDOUT: !members: diff --git a/toolchain/check/testdata/class/adapt.carbon b/toolchain/check/testdata/class/adapt.carbon index 4af5497d85f23..e4a17e63f5c61 100644 --- a/toolchain/check/testdata/class/adapt.carbon +++ b/toolchain/check/testdata/class/adapt.carbon @@ -102,7 +102,7 @@ fn F(a: AdaptNotExtend) { // CHECK:STDOUT: // CHECK:STDOUT: class @SomeClassAdapter { // CHECK:STDOUT: %SomeClass.ref: type = name_ref SomeClass, file.%SomeClass.decl [template = constants.%SomeClass] -// CHECK:STDOUT: adapt_decl %SomeClass.ref +// CHECK:STDOUT: adapt_decl %SomeClass.ref [template] // CHECK:STDOUT: %.loc11: = complete_type_witness %.3 [template = constants.%.4] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -119,7 +119,7 @@ fn F(a: AdaptNotExtend) { // CHECK:STDOUT: %.loc14_23.2: type = value_of_initializer %int.make_type_signed.loc14_23 [template = constants.%i32] // CHECK:STDOUT: %.loc14_23.3: type = converted %int.make_type_signed.loc14_23, %.loc14_23.2 [template = constants.%i32] // CHECK:STDOUT: %.loc14_26: type = struct_type {.a: %i32, .b: %i32} [template = constants.%.3] -// CHECK:STDOUT: adapt_decl %.loc14_26 +// CHECK:STDOUT: adapt_decl %.loc14_26 [template] // CHECK:STDOUT: %.loc15: = complete_type_witness %.3 [template = constants.%.4] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -177,7 +177,7 @@ fn F(a: AdaptNotExtend) { // CHECK:STDOUT: // CHECK:STDOUT: class @AdaptNotExtend { // CHECK:STDOUT: %Adapted.ref: type = name_ref Adapted, file.%Adapted.decl [template = constants.%Adapted] -// CHECK:STDOUT: adapt_decl %Adapted.ref +// CHECK:STDOUT: adapt_decl %Adapted.ref [template] // CHECK:STDOUT: %.loc10: = complete_type_witness %.1 [template = constants.%.2] // CHECK:STDOUT: // CHECK:STDOUT: !members: diff --git a/toolchain/check/testdata/class/extend_adapt.carbon b/toolchain/check/testdata/class/extend_adapt.carbon index e82f1aef71a9a..d43443bfcced7 100644 --- a/toolchain/check/testdata/class/extend_adapt.carbon +++ b/toolchain/check/testdata/class/extend_adapt.carbon @@ -200,7 +200,7 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: class @SomeClassAdapter { // CHECK:STDOUT: %SomeClass.ref: type = name_ref SomeClass, file.%SomeClass.decl [template = constants.%SomeClass] -// CHECK:STDOUT: adapt_decl %SomeClass.ref +// CHECK:STDOUT: adapt_decl %SomeClass.ref [template] // CHECK:STDOUT: %.loc17: = complete_type_witness %.3 [template = constants.%.4] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -319,7 +319,7 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: class @SomeClassAdapter { // CHECK:STDOUT: %SomeClass.ref: type = name_ref SomeClass, file.%SomeClass.decl [template = constants.%SomeClass] -// CHECK:STDOUT: adapt_decl %SomeClass.ref +// CHECK:STDOUT: adapt_decl %SomeClass.ref [template] // CHECK:STDOUT: %.loc10: = complete_type_witness %.1 [template = constants.%.2] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -413,7 +413,7 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: class @SomeClassAdapter { // CHECK:STDOUT: %SomeClass.ref: type = name_ref SomeClass, file.%SomeClass.decl [template = constants.%SomeClass] -// CHECK:STDOUT: adapt_decl %SomeClass.ref +// CHECK:STDOUT: adapt_decl %SomeClass.ref [template] // CHECK:STDOUT: %.loc11: = complete_type_witness %.3 [template = constants.%.4] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -488,7 +488,7 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: %.loc5_30.2: type = value_of_initializer %int.make_type_signed.loc5_30 [template = constants.%i32] // CHECK:STDOUT: %.loc5_30.3: type = converted %int.make_type_signed.loc5_30, %.loc5_30.2 [template = constants.%i32] // CHECK:STDOUT: %.loc5_33: type = struct_type {.a: %i32, .b: %i32} [template = constants.%.2] -// CHECK:STDOUT: adapt_decl %.loc5_33 +// CHECK:STDOUT: adapt_decl %.loc5_33 [template] // CHECK:STDOUT: %.loc6: = complete_type_witness %.2 [template = constants.%.4] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -564,7 +564,7 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: %.loc5_26.3: type = value_of_initializer %int.make_type_signed.loc5_22 [template = constants.%i32] // CHECK:STDOUT: %.loc5_26.4: type = converted %int.make_type_signed.loc5_22, %.loc5_26.3 [template = constants.%i32] // CHECK:STDOUT: %.loc5_26.5: type = converted %.loc5_25, constants.%tuple.type.2 [template = constants.%tuple.type.2] -// CHECK:STDOUT: adapt_decl %.loc5_26.5 +// CHECK:STDOUT: adapt_decl %.loc5_26.5 [template] // CHECK:STDOUT: %.loc6: = complete_type_witness %tuple.type.2 [template = constants.%.3] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -655,7 +655,7 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: %int.make_type_signed: init type = call %MakeInt.ref(%.loc7_24) [template = constants.%i32] // CHECK:STDOUT: %.loc7_27.1: type = value_of_initializer %int.make_type_signed [template = constants.%i32] // CHECK:STDOUT: %.loc7_27.2: type = converted %int.make_type_signed, %.loc7_27.1 [template = constants.%i32] -// CHECK:STDOUT: adapt_decl %.loc7_27.2 +// CHECK:STDOUT: adapt_decl %.loc7_27.2 [template] // CHECK:STDOUT: %.loc8: = complete_type_witness %i32 [template = constants.%.2] // CHECK:STDOUT: // CHECK:STDOUT: !members: diff --git a/toolchain/check/testdata/class/fail_abstract.carbon b/toolchain/check/testdata/class/fail_abstract.carbon index ae2425d7777f5..758e3570b5d2f 100644 --- a/toolchain/check/testdata/class/fail_abstract.carbon +++ b/toolchain/check/testdata/class/fail_abstract.carbon @@ -361,7 +361,7 @@ fn CallReturnAbstract() { // CHECK:STDOUT: // CHECK:STDOUT: class @Adapter { // CHECK:STDOUT: %Abstract.ref: type = name_ref Abstract, file.%Abstract.decl [template = constants.%Abstract] -// CHECK:STDOUT: adapt_decl +// CHECK:STDOUT: adapt_decl [template] // CHECK:STDOUT: %.loc17: = complete_type_witness [template = ] // CHECK:STDOUT: // CHECK:STDOUT: !members: diff --git a/toolchain/check/testdata/class/fail_adapt_bad_decl.carbon b/toolchain/check/testdata/class/fail_adapt_bad_decl.carbon index 0bf44aace8dbe..a7335cdef47b4 100644 --- a/toolchain/check/testdata/class/fail_adapt_bad_decl.carbon +++ b/toolchain/check/testdata/class/fail_adapt_bad_decl.carbon @@ -140,7 +140,7 @@ class C { // CHECK:STDOUT: class @Bad { // CHECK:STDOUT: %.loc12_9: Core.IntLiteral = int_value 100 [template = constants.%.1] // CHECK:STDOUT: %.loc12_12: type = converted %.loc12_9, [template = ] -// CHECK:STDOUT: adapt_decl +// CHECK:STDOUT: adapt_decl [template] // CHECK:STDOUT: %.loc13: = complete_type_witness [template = ] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -192,7 +192,7 @@ class C { // CHECK:STDOUT: class @Bad { // CHECK:STDOUT: %.loc12_16: Core.IntLiteral = int_value 100 [template = constants.%.1] // CHECK:STDOUT: %.loc12_19: type = converted %.loc12_16, [template = ] -// CHECK:STDOUT: adapt_decl +// CHECK:STDOUT: adapt_decl [template] // CHECK:STDOUT: %.loc13: = complete_type_witness [template = ] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -238,7 +238,7 @@ class C { // CHECK:STDOUT: class @MultipleAdapts { // CHECK:STDOUT: %.loc5_10: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc5_11: type = converted %.loc5_10, constants.%empty_tuple.type [template = constants.%empty_tuple.type] -// CHECK:STDOUT: adapt_decl %.loc5_11 +// CHECK:STDOUT: adapt_decl %.loc5_11 [template] // CHECK:STDOUT: %.loc13: %.1 = struct_literal () // CHECK:STDOUT: %.loc14: = complete_type_witness %empty_tuple.type [template = constants.%.2] // CHECK:STDOUT: @@ -249,7 +249,7 @@ class C { // CHECK:STDOUT: class @MultipleAdaptsSameType { // CHECK:STDOUT: %.loc17_10: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc17_11: type = converted %.loc17_10, constants.%empty_tuple.type [template = constants.%empty_tuple.type] -// CHECK:STDOUT: adapt_decl %.loc17_11 +// CHECK:STDOUT: adapt_decl %.loc17_11 [template] // CHECK:STDOUT: %.loc25: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc26: = complete_type_witness %empty_tuple.type [template = constants.%.2] // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/fail_adapt_bad_type.carbon b/toolchain/check/testdata/class/fail_adapt_bad_type.carbon index f883cf736b72d..702fcf9e6a81c 100644 --- a/toolchain/check/testdata/class/fail_adapt_bad_type.carbon +++ b/toolchain/check/testdata/class/fail_adapt_bad_type.carbon @@ -53,7 +53,7 @@ class AdaptIncomplete { // CHECK:STDOUT: // CHECK:STDOUT: class @AdaptIncomplete { // CHECK:STDOUT: %Incomplete.ref: type = name_ref Incomplete, file.%Incomplete.decl [template = constants.%Incomplete] -// CHECK:STDOUT: adapt_decl +// CHECK:STDOUT: adapt_decl [template] // CHECK:STDOUT: %.loc14: = complete_type_witness [template = ] // CHECK:STDOUT: // CHECK:STDOUT: !members: diff --git a/toolchain/check/testdata/class/fail_adapt_modifiers.carbon b/toolchain/check/testdata/class/fail_adapt_modifiers.carbon index 3f220a98b9851..e65850414416e 100644 --- a/toolchain/check/testdata/class/fail_adapt_modifiers.carbon +++ b/toolchain/check/testdata/class/fail_adapt_modifiers.carbon @@ -103,7 +103,7 @@ class C5 { // CHECK:STDOUT: // CHECK:STDOUT: class @C1 { // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B] -// CHECK:STDOUT: adapt_decl %B.ref +// CHECK:STDOUT: adapt_decl %B.ref [template] // CHECK:STDOUT: %.loc19: = complete_type_witness %.1 [template = constants.%.2] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -112,7 +112,7 @@ class C5 { // CHECK:STDOUT: // CHECK:STDOUT: class @C2 { // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B] -// CHECK:STDOUT: adapt_decl %B.ref +// CHECK:STDOUT: adapt_decl %B.ref [template] // CHECK:STDOUT: %.loc27: = complete_type_witness %.1 [template = constants.%.2] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -121,7 +121,7 @@ class C5 { // CHECK:STDOUT: // CHECK:STDOUT: class @C3 { // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B] -// CHECK:STDOUT: adapt_decl %B.ref +// CHECK:STDOUT: adapt_decl %B.ref [template] // CHECK:STDOUT: %.loc35: = complete_type_witness %.1 [template = constants.%.2] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -130,7 +130,7 @@ class C5 { // CHECK:STDOUT: // CHECK:STDOUT: class @C4 { // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B] -// CHECK:STDOUT: adapt_decl %B.ref +// CHECK:STDOUT: adapt_decl %B.ref [template] // CHECK:STDOUT: %.loc46: = complete_type_witness %.1 [template = constants.%.2] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -140,7 +140,7 @@ class C5 { // CHECK:STDOUT: // CHECK:STDOUT: class @C5 { // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B] -// CHECK:STDOUT: adapt_decl %B.ref +// CHECK:STDOUT: adapt_decl %B.ref [template] // CHECK:STDOUT: %.loc56: = complete_type_witness %.1 [template = constants.%.2] // CHECK:STDOUT: // CHECK:STDOUT: !members: diff --git a/toolchain/check/testdata/class/fail_adapt_with_base.carbon b/toolchain/check/testdata/class/fail_adapt_with_base.carbon index f5052dca21f5a..97ee3a170f05d 100644 --- a/toolchain/check/testdata/class/fail_adapt_with_base.carbon +++ b/toolchain/check/testdata/class/fail_adapt_with_base.carbon @@ -58,7 +58,7 @@ base class AdaptWithVirtual { // CHECK:STDOUT: class @AdaptWithVirtual { // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] {} {} // CHECK:STDOUT: %Simple.ref: type = name_ref Simple, file.%Simple.decl [template = constants.%Simple] -// CHECK:STDOUT: adapt_decl %Simple.ref +// CHECK:STDOUT: adapt_decl %Simple.ref [template] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%AdaptWithVirtual diff --git a/toolchain/check/testdata/class/fail_adapt_with_subobjects.carbon b/toolchain/check/testdata/class/fail_adapt_with_subobjects.carbon index 3cfb786b90e9f..53a29cfa84b55 100644 --- a/toolchain/check/testdata/class/fail_adapt_with_subobjects.carbon +++ b/toolchain/check/testdata/class/fail_adapt_with_subobjects.carbon @@ -119,7 +119,7 @@ class AdaptWithBaseAndFields { // CHECK:STDOUT: %int.make_type_signed: init type = call constants.%Int(%.loc10_9) [template = constants.%i32] // CHECK:STDOUT: %.loc10_12.1: type = value_of_initializer %int.make_type_signed [template = constants.%i32] // CHECK:STDOUT: %.loc10_12.2: type = converted %int.make_type_signed, %.loc10_12.1 [template = constants.%i32] -// CHECK:STDOUT: adapt_decl %.loc10_12.2 +// CHECK:STDOUT: adapt_decl %.loc10_12.2 [template] // CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base] // CHECK:STDOUT: %.loc15: %.5 = base_decl %Base.ref, element0 [template] // CHECK:STDOUT: @@ -166,7 +166,7 @@ class AdaptWithBaseAndFields { // CHECK:STDOUT: %int.make_type_signed.loc8: init type = call constants.%Int(%.loc8_9) [template = constants.%i32] // CHECK:STDOUT: %.loc8_12.1: type = value_of_initializer %int.make_type_signed.loc8 [template = constants.%i32] // CHECK:STDOUT: %.loc8_12.2: type = converted %int.make_type_signed.loc8, %.loc8_12.1 [template = constants.%i32] -// CHECK:STDOUT: adapt_decl %.loc8_12.2 +// CHECK:STDOUT: adapt_decl %.loc8_12.2 [template] // CHECK:STDOUT: %.loc13_10.1: Core.IntLiteral = int_value 32 [template = constants.%.1] // CHECK:STDOUT: %int.make_type_signed.loc13: init type = call constants.%Int(%.loc13_10.1) [template = constants.%i32] // CHECK:STDOUT: %.loc13_10.2: type = value_of_initializer %int.make_type_signed.loc13 [template = constants.%i32] @@ -183,7 +183,7 @@ class AdaptWithBaseAndFields { // CHECK:STDOUT: %int.make_type_signed.loc20: init type = call constants.%Int(%.loc20_9) [template = constants.%i32] // CHECK:STDOUT: %.loc20_12.1: type = value_of_initializer %int.make_type_signed.loc20 [template = constants.%i32] // CHECK:STDOUT: %.loc20_12.2: type = converted %int.make_type_signed.loc20, %.loc20_12.1 [template = constants.%i32] -// CHECK:STDOUT: adapt_decl %.loc20_12.2 +// CHECK:STDOUT: adapt_decl %.loc20_12.2 [template] // CHECK:STDOUT: %.loc25_10.1: Core.IntLiteral = int_value 32 [template = constants.%.1] // CHECK:STDOUT: %int.make_type_signed.loc25: init type = call constants.%Int(%.loc25_10.1) [template = constants.%i32] // CHECK:STDOUT: %.loc25_10.2: type = value_of_initializer %int.make_type_signed.loc25 [template = constants.%i32] @@ -258,7 +258,7 @@ class AdaptWithBaseAndFields { // CHECK:STDOUT: %.loc8_8: %.6 = field_decl n, element1 [template] // CHECK:STDOUT: %.loc15_10: %.1 = struct_literal () // CHECK:STDOUT: %.loc15_11: type = converted %.loc15_10, constants.%.1 [template = constants.%.1] -// CHECK:STDOUT: adapt_decl %.loc15_11 +// CHECK:STDOUT: adapt_decl %.loc15_11 [template] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%AdaptWithBaseAndFields diff --git a/toolchain/check/testdata/class/generic/init.carbon b/toolchain/check/testdata/class/generic/init.carbon index 5c2807cf1081d..f1f0fc0f628c3 100644 --- a/toolchain/check/testdata/class/generic/init.carbon +++ b/toolchain/check/testdata/class/generic/init.carbon @@ -332,7 +332,7 @@ fn InitFromAdaptedSpecific(x: i32) -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: class { // CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc4_13.1 [symbolic = %T.loc4_13.2 (constants.%T)] -// CHECK:STDOUT: adapt_decl %T.ref +// CHECK:STDOUT: adapt_decl %T.ref [template] // CHECK:STDOUT: %.loc6_1.1: = complete_type_witness %T [symbolic = %.loc6_1.2 (constants.%.1)] // CHECK:STDOUT: // CHECK:STDOUT: !members: diff --git a/toolchain/check/testdata/class/init_adapt.carbon b/toolchain/check/testdata/class/init_adapt.carbon index 1d78c5944f404..1a0fda72eea91 100644 --- a/toolchain/check/testdata/class/init_adapt.carbon +++ b/toolchain/check/testdata/class/init_adapt.carbon @@ -196,7 +196,7 @@ var e: C = MakeAdaptC(); // CHECK:STDOUT: // CHECK:STDOUT: class @AdaptC { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [template = constants.%C] -// CHECK:STDOUT: adapt_decl %C.ref +// CHECK:STDOUT: adapt_decl %C.ref [template] // CHECK:STDOUT: %.loc11: = complete_type_witness %.3 [template = constants.%.4] // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -364,7 +364,7 @@ var e: C = MakeAdaptC(); // CHECK:STDOUT: // CHECK:STDOUT: class @AdaptC { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [template = constants.%C] -// CHECK:STDOUT: adapt_decl %C.ref +// CHECK:STDOUT: adapt_decl %C.ref [template] // CHECK:STDOUT: %.loc11: = complete_type_witness %.3 [template = constants.%.4] // CHECK:STDOUT: // CHECK:STDOUT: !members: diff --git a/toolchain/lower/constant.cpp b/toolchain/lower/constant.cpp index 38e58faab7de2..a4cba1882101b 100644 --- a/toolchain/lower/constant.cpp +++ b/toolchain/lower/constant.cpp @@ -99,29 +99,12 @@ static auto EmitAggregateConstant(ConstantContext& context, return ConstantType::get(llvm_type, elements); } -// For each instruction InstT, there is a function below to convert it to an -// `llvm::Constant*`: +// For each instruction InstT that can be emitted as a constant, there is a +// function below to convert it to an `llvm::Constant*`: // // auto EmitAsConstant(ConstantContext& context, SemIR::InstT inst) // -> llvm::Constant*; -template - requires(InstT::Kind.constant_kind() == SemIR::InstConstantKind::Never || - InstT::Kind.constant_kind() == SemIR::InstConstantKind::SymbolicOnly) -static auto EmitAsConstant(ConstantContext& /*context*/, InstT inst) - -> llvm::Constant* { - CARBON_FATAL("Unexpected constant instruction kind {0}", inst); -} - -// For constants that are always of type `type`, produce the trivial runtime -// representation of type `type`. -template - requires(InstT::Kind.is_type() == SemIR::InstIsType::Always) -static auto EmitAsConstant(ConstantContext& context, InstT /*inst*/) - -> llvm::Constant* { - return context.GetTypeAsValue(); -} - static auto EmitAsConstant(ConstantContext& context, SemIR::StructValue inst) -> llvm::Constant* { return EmitAggregateConstant( @@ -190,20 +173,6 @@ static auto EmitAsConstant(ConstantContext& context, SemIR::FloatLiteral inst) return llvm::ConstantFP::get(context.GetType(inst.type_id), value); } -static auto EmitAsConstant(ConstantContext& context, - SemIR::InterfaceWitness inst) -> llvm::Constant* { - // TODO: For dynamic dispatch, we might want to lower witness tables as - // constants. - return context.GetUnusedConstant(inst.type_id); -} - -static auto EmitAsConstant(ConstantContext& /*context*/, - SemIR::ImplDecl /*inst*/) -> llvm::Constant* { - // An ImplDecl isn't a value, so this constant value won't ever be used. - // It also doesn't even have a type, so we can't use GetUnusedConstant. - return nullptr; -} - static auto EmitAsConstant(ConstantContext& context, SemIR::IntValue inst) -> llvm::Constant* { auto* type = context.GetType(inst.type_id); @@ -240,6 +209,24 @@ static auto EmitAsConstant(ConstantContext& /*context*/, CARBON_FATAL("TODO: Add support: {0}", inst); } +template +static auto MaybeEmitAsConstant(ConstantContext& context, InstT inst) + -> llvm::Constant* { + if constexpr (InstT::Kind.constant_kind() == SemIR::InstConstantKind::Never || + InstT::Kind.constant_kind() == + SemIR::InstConstantKind::SymbolicOnly) { + CARBON_FATAL("Unexpected constant instruction kind {0}", inst); + } else if constexpr (!InstT::Kind.is_lowered()) { + // This instruction has a constant value, but that constant value will never + // be used by lowering. + return nullptr; + } else if constexpr (InstT::Kind.is_type() == SemIR::InstIsType::Always) { + return context.GetTypeAsValue(); + } else { + return EmitAsConstant(context, inst); + } +} + auto LowerConstants(FileContext& file_context, llvm::MutableArrayRef constants) -> void { ConstantContext context(file_context, constants); @@ -267,10 +254,10 @@ auto LowerConstants(FileContext& file_context, } llvm::Constant* value = nullptr; CARBON_KIND_SWITCH(inst) { -#define CARBON_SEM_IR_INST_KIND(Name) \ - case CARBON_KIND(SemIR::Name const_inst): { \ - value = EmitAsConstant(context, const_inst); \ - break; \ +#define CARBON_SEM_IR_INST_KIND(Name) \ + case CARBON_KIND(SemIR::Name const_inst): { \ + value = MaybeEmitAsConstant(context, const_inst); \ + break; \ } #include "toolchain/sem_ir/inst_kind.def" } diff --git a/toolchain/sem_ir/typed_insts.h b/toolchain/sem_ir/typed_insts.h index e9c32f430e22f..d444accfd78bf 100644 --- a/toolchain/sem_ir/typed_insts.h +++ b/toolchain/sem_ir/typed_insts.h @@ -62,7 +62,9 @@ namespace Carbon::SemIR { // An adapted type declaration in a class, of the form `adapt T;`. struct AdaptDecl { static constexpr auto Kind = InstKind::AdaptDecl.Define( - {.ir_name = "adapt_decl", .is_lowered = false}); + {.ir_name = "adapt_decl", + .constant_kind = InstConstantKind::Always, + .is_lowered = false}); // No type_id; this is not a value. InstId adapted_type_inst_id; @@ -749,6 +751,8 @@ struct InterfaceWitness { static constexpr auto Kind = InstKind::InterfaceWitness.Define( {.ir_name = "interface_witness", .constant_kind = InstConstantKind::Conditional, + // TODO: For dynamic dispatch, we might want to lower witness tables as + // constants. .is_lowered = false}); // Always the builtin witness type. From 2c1c938ff0f79c712475a31f366d9b91d3e46833 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Thu, 21 Nov 2024 19:50:42 +0000 Subject: [PATCH 04/11] Fix importing of adapters --- toolchain/check/context.cpp | 8 +- toolchain/check/import_ref.cpp | 11 +- .../check/testdata/class/generic/adapt.carbon | 912 ++++++++++++++++++ 3 files changed, 928 insertions(+), 3 deletions(-) create mode 100644 toolchain/check/testdata/class/generic/adapt.carbon diff --git a/toolchain/check/context.cpp b/toolchain/check/context.cpp index 914e3b7f9da38..adac499177f9f 100644 --- a/toolchain/check/context.cpp +++ b/toolchain/check/context.cpp @@ -947,7 +947,13 @@ class TypeCompleter { if (inst.specific_id.is_valid()) { ResolveSpecificDefinition(context_, inst.specific_id); } - Push(class_info.GetObjectRepr(context_.sem_ir(), inst.specific_id)); + if (auto adapted_type_id = + class_info.GetAdaptedType(context_.sem_ir(), inst.specific_id); + adapted_type_id.is_valid()) { + Push(adapted_type_id); + } else { + Push(class_info.GetObjectRepr(context_.sem_ir(), inst.specific_id)); + } break; } case CARBON_KIND(SemIR::ConstType inst): { diff --git a/toolchain/check/import_ref.cpp b/toolchain/check/import_ref.cpp index bd2c443977a41..6a3189e269f3e 100644 --- a/toolchain/check/import_ref.cpp +++ b/toolchain/check/import_ref.cpp @@ -1481,7 +1481,8 @@ class ImportRefResolver { auto AddClassDefinition(const SemIR::Class& import_class, SemIR::Class& new_class, SemIR::InstId complete_type_witness_id, - SemIR::InstId base_id) -> void { + SemIR::InstId base_id, + SemIR::InstId adapt_id) -> void { new_class.definition_id = new_class.first_owning_decl_id; new_class.complete_type_witness_id = complete_type_witness_id; @@ -1501,6 +1502,9 @@ class ImportRefResolver { if (import_class.base_id.is_valid()) { new_class.base_id = base_id; } + if (import_class.adapt_id.is_valid()) { + new_class.adapt_id = adapt_id; + } } auto TryResolveTypedInst(SemIR::ClassDecl inst, @@ -1561,6 +1565,9 @@ class ImportRefResolver { auto base_id = import_class.base_id.is_valid() ? GetLocalConstantInstId(import_class.base_id) : SemIR::InstId::Invalid; + auto adapt_id = import_class.adapt_id.is_valid() + ? GetLocalConstantInstId(import_class.adapt_id) + : SemIR::InstId::Invalid; if (HasNewWork()) { return Retry(class_const_id); @@ -1580,7 +1587,7 @@ class ImportRefResolver { if (import_class.is_defined()) { AddClassDefinition(import_class, new_class, complete_type_witness_id, - base_id); + base_id, adapt_id); } return ResolveAsConstant(class_const_id); diff --git a/toolchain/check/testdata/class/generic/adapt.carbon b/toolchain/check/testdata/class/generic/adapt.carbon new file mode 100644 index 0000000000000..dab0d40c2205f --- /dev/null +++ b/toolchain/check/testdata/class/generic/adapt.carbon @@ -0,0 +1,912 @@ +// 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 +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/class/generic/adapt.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/class/generic/adapt.carbon + +// --- adapt_specific_type.carbon + +library "[[@TEST_NAME]]"; + +class C(T:! type) { + var x: T; +} + +class Adapter { + adapt C(i32); +} + +fn Access(a: Adapter) -> C(i32) { + // CHECK:STDERR: adapt_specific_type.carbon:[[@LINE+7]]:3: error: cannot implicitly convert from `i32` to `C(i32)` [ImplicitAsConversionFailure] + // CHECK:STDERR: return (a as C(i32)).x; + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: adapt_specific_type.carbon:[[@LINE+4]]:3: note: type `i32` does not implement interface `ImplicitAs(C(i32))` [MissingImplInMemberAccessNote] + // CHECK:STDERR: return (a as C(i32)).x; + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: + return (a as C(i32)).x; +} + +// --- import_adapt_specific_type.carbon + +library "[[@TEST_NAME]]"; + +import library "adapt_specific_type"; + +fn ImportedAccess(a: Adapter) -> i32 { + return (a as C(i32)).x; +} + +// --- fail_todo_extend_adapt_specific_type.carbon + +library "[[@TEST_NAME]]"; + +class C(T:! type) { + var x: T; +} + +class Adapter { + extend adapt C(i32); +} + +fn Access(a: Adapter) -> C(i32) { + // TODO: This should presumably work, but the design doesn't say how yet. + // CHECK:STDERR: fail_todo_extend_adapt_specific_type.carbon:[[@LINE+13]]:3: error: cannot implicitly convert from `i32` to `C(i32)` [ImplicitAsConversionFailure] + // CHECK:STDERR: return a.x; + // CHECK:STDERR: ^~~~~~~~~~~ + // CHECK:STDERR: fail_todo_extend_adapt_specific_type.carbon:[[@LINE+10]]:3: note: type `i32` does not implement interface `ImplicitAs(C(i32))` [MissingImplInMemberAccessNote] + // CHECK:STDERR: return a.x; + // CHECK:STDERR: ^~~~~~~~~~~ + // CHECK:STDERR: + // CHECK:STDERR: fail_todo_extend_adapt_specific_type.carbon:[[@LINE+6]]:10: error: cannot implicitly convert from `Adapter` to `C(i32)` [ImplicitAsConversionFailure] + // CHECK:STDERR: return a.x; + // CHECK:STDERR: ^~~ + // CHECK:STDERR: fail_todo_extend_adapt_specific_type.carbon:[[@LINE+3]]:10: note: type `Adapter` does not implement interface `ImplicitAs(C(i32))` [MissingImplInMemberAccessNote] + // CHECK:STDERR: return a.x; + // CHECK:STDERR: ^~~ + return a.x; +} + +// --- fail_todo_import_extend_adapt_specific_type.carbon + +library "[[@TEST_NAME]]"; + +import library "adapt_specific_type"; + +fn ImportedAccess(a: Adapter) -> i32 { + // TODO: This should presumably work, but the design doesn't say how yet. + return (a as C(i32)).x; +} + +// --- adapt_generic_type.carbon + +library "[[@TEST_NAME]]"; + +class Adapter(T:! type) { + adapt T; +} + +fn Convert(a: Adapter(i32)) -> i32 { + return a as i32; +} + +// --- import_adapt_generic_type.carbon + +library "[[@TEST_NAME]]"; + +import library "adapt_generic_type"; + +fn ImportedConvert(a: Adapter(i32)) -> i32 { + return a as i32; +} + +class C { + var n: i32; +} + +fn ImportedConvertLocal(a: Adapter(C)) -> i32 { + return (a as C).n; +} + +// CHECK:STDOUT: --- adapt_specific_type.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] +// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0 [symbolic] +// CHECK:STDOUT: %C.type: type = generic_class_type @C [template] +// CHECK:STDOUT: %C.1: %C.type = struct_value () [template] +// CHECK:STDOUT: %C.2: type = class_type @C, @C(%T) [symbolic] +// CHECK:STDOUT: %.1: type = unbound_element_type %C.2, %T [symbolic] +// CHECK:STDOUT: %.2: type = struct_type {.x: %T} [symbolic] +// CHECK:STDOUT: %.3: = complete_type_witness %.2 [symbolic] +// CHECK:STDOUT: %Adapter: type = class_type @Adapter [template] +// CHECK:STDOUT: %.4: Core.IntLiteral = int_value 32 [template] +// CHECK:STDOUT: %Int.type: type = fn_type @Int [template] +// CHECK:STDOUT: %Int: %Int.type = struct_value () [template] +// CHECK:STDOUT: %i32: type = int_type signed, %.4 [template] +// CHECK:STDOUT: %C.3: type = class_type @C, @C(%i32) [template] +// CHECK:STDOUT: %.5: type = unbound_element_type %C.3, %i32 [template] +// CHECK:STDOUT: %.6: type = struct_type {.x: %i32} [template] +// CHECK:STDOUT: %.7: = complete_type_witness %.6 [template] +// CHECK:STDOUT: %Access.type: type = fn_type @Access [template] +// CHECK:STDOUT: %Access: %Access.type = struct_value () [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { +// CHECK:STDOUT: .Int = %import_ref.1 +// CHECK:STDOUT: .ImplicitAs = %import_ref.2 +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .Adapter = %Adapter.decl +// CHECK:STDOUT: .Access = %Access.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %C.decl: %C.type = class_decl @C [template = constants.%C.1] { +// CHECK:STDOUT: %T.patt.loc4_9.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_9.2 (constants.%T.patt)] +// CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc4_9.1, runtime_param [symbolic = %T.patt.loc4_9.2 (constants.%T.patt)] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %T.param: type = value_param runtime_param +// CHECK:STDOUT: %T.loc4_9.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc4_9.2 (constants.%T)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %Adapter.decl: type = class_decl @Adapter [template = constants.%Adapter] {} {} +// CHECK:STDOUT: %Access.decl: %Access.type = fn_decl @Access [template = constants.%Access] { +// CHECK:STDOUT: %a.patt: %Adapter = binding_pattern a +// CHECK:STDOUT: %a.param_patt: %Adapter = value_param_pattern %a.patt, runtime_param0 +// CHECK:STDOUT: %return.patt: %C.3 = return_slot_pattern +// CHECK:STDOUT: %return.param_patt: %C.3 = out_param_pattern %return.patt, runtime_param1 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %Adapter.ref: type = name_ref Adapter, file.%Adapter.decl [template = constants.%Adapter] +// CHECK:STDOUT: %C.ref.loc12: %C.type = name_ref C, file.%C.decl [template = constants.%C.1] +// CHECK:STDOUT: %.loc12_28: Core.IntLiteral = int_value 32 [template = constants.%.4] +// CHECK:STDOUT: %int.make_type_signed.loc12: init type = call constants.%Int(%.loc12_28) [template = constants.%i32] +// CHECK:STDOUT: %.loc12_27.1: type = value_of_initializer %int.make_type_signed.loc12 [template = constants.%i32] +// CHECK:STDOUT: %.loc12_27.2: type = converted %int.make_type_signed.loc12, %.loc12_27.1 [template = constants.%i32] +// CHECK:STDOUT: %C.loc12: type = class_type @C, @C(constants.%i32) [template = constants.%C.3] +// CHECK:STDOUT: %a.param: %Adapter = value_param runtime_param0 +// CHECK:STDOUT: %a: %Adapter = bind_name a, %a.param +// CHECK:STDOUT: %return.param: ref %C.3 = out_param runtime_param1 +// CHECK:STDOUT: %return: ref %C.3 = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic class @C(%T.loc4_9.1: type) { +// CHECK:STDOUT: %T.loc4_9.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_9.2 (constants.%T)] +// CHECK:STDOUT: %T.patt.loc4_9.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_9.2 (constants.%T.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C: type = class_type @C, @C(%T.loc4_9.2) [symbolic = %C (constants.%C.2)] +// CHECK:STDOUT: %.loc5_8.2: type = unbound_element_type @C.%C (%C.2), @C.%T.loc4_9.2 (%T) [symbolic = %.loc5_8.2 (constants.%.1)] +// CHECK:STDOUT: %.loc6_1.2: type = struct_type {.x: @C.%T.loc4_9.2 (%T)} [symbolic = %.loc6_1.2 (constants.%.2)] +// CHECK:STDOUT: %.loc6_1.3: = complete_type_witness @C.%.loc6_1.2 (%.2) [symbolic = %.loc6_1.3 (constants.%.3)] +// CHECK:STDOUT: +// CHECK:STDOUT: class { +// CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc4_9.1 [symbolic = %T.loc4_9.2 (constants.%T)] +// CHECK:STDOUT: %.loc5_8.1: @C.%.loc5_8.2 (%.1) = field_decl x, element0 [template] +// CHECK:STDOUT: %.loc6_1.1: = complete_type_witness %.2 [symbolic = %.loc6_1.3 (constants.%.3)] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C.2 +// CHECK:STDOUT: .x = %.loc5_8.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Adapter { +// CHECK:STDOUT: %C.ref: %C.type = name_ref C, file.%C.decl [template = constants.%C.1] +// CHECK:STDOUT: %.loc9_11: Core.IntLiteral = int_value 32 [template = constants.%.4] +// CHECK:STDOUT: %int.make_type_signed: init type = call constants.%Int(%.loc9_11) [template = constants.%i32] +// CHECK:STDOUT: %.loc9_10.1: type = value_of_initializer %int.make_type_signed [template = constants.%i32] +// CHECK:STDOUT: %.loc9_10.2: type = converted %int.make_type_signed, %.loc9_10.1 [template = constants.%i32] +// CHECK:STDOUT: %C: type = class_type @C, @C(constants.%i32) [template = constants.%C.3] +// CHECK:STDOUT: adapt_decl %C [template] +// CHECK:STDOUT: %.loc10: = complete_type_witness %.6 [template = constants.%.7] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%Adapter +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Access(%a.param_patt: %Adapter) -> %return: %C.3 { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %a.ref: %Adapter = name_ref a, %a +// CHECK:STDOUT: %C.ref.loc20: %C.type = name_ref C, file.%C.decl [template = constants.%C.1] +// CHECK:STDOUT: %.loc20_18: Core.IntLiteral = int_value 32 [template = constants.%.4] +// CHECK:STDOUT: %int.make_type_signed.loc20: init type = call constants.%Int(%.loc20_18) [template = constants.%i32] +// CHECK:STDOUT: %.loc20_17.1: type = value_of_initializer %int.make_type_signed.loc20 [template = constants.%i32] +// CHECK:STDOUT: %.loc20_17.2: type = converted %int.make_type_signed.loc20, %.loc20_17.1 [template = constants.%i32] +// CHECK:STDOUT: %C.loc20: type = class_type @C, @C(constants.%i32) [template = constants.%C.3] +// CHECK:STDOUT: %.loc20_13.1: %C.3 = as_compatible %a.ref +// CHECK:STDOUT: %.loc20_13.2: %C.3 = converted %a.ref, %.loc20_13.1 +// CHECK:STDOUT: %x.ref: %.5 = name_ref x, @C.%.loc5_8.1 [template = @C.%.loc5_8.1] +// CHECK:STDOUT: %.loc20_23.1: ref %i32 = class_element_access %.loc20_13.2, element0 +// CHECK:STDOUT: %.loc20_23.2: %i32 = bind_value %.loc20_23.1 +// CHECK:STDOUT: %.loc20_25: %C.3 = converted %.loc20_23.2, [template = ] +// CHECK:STDOUT: return to %return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C(constants.%T) { +// CHECK:STDOUT: %T.loc4_9.2 => constants.%T +// CHECK:STDOUT: %T.patt.loc4_9.2 => constants.%T +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C(%T.loc4_9.2) { +// CHECK:STDOUT: %T.loc4_9.2 => constants.%T +// CHECK:STDOUT: %T.patt.loc4_9.2 => constants.%T +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C(constants.%i32) { +// CHECK:STDOUT: %T.loc4_9.2 => constants.%i32 +// CHECK:STDOUT: %T.patt.loc4_9.2 => constants.%i32 +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C => constants.%C.3 +// CHECK:STDOUT: %.loc5_8.2 => constants.%.5 +// CHECK:STDOUT: %.loc6_1.2 => constants.%.6 +// CHECK:STDOUT: %.loc6_1.3 => constants.%.7 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- import_adapt_specific_type.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %Adapter: type = class_type @Adapter [template] +// CHECK:STDOUT: %.1: Core.IntLiteral = int_value 32 [template] +// CHECK:STDOUT: %i32: type = int_type signed, %.1 [template] +// CHECK:STDOUT: %C.type: type = generic_class_type @C [template] +// CHECK:STDOUT: %C.1: %C.type = struct_value () [template] +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] +// CHECK:STDOUT: %.2: type = struct_type {.x: %T} [symbolic] +// CHECK:STDOUT: %.3: = complete_type_witness %.2 [symbolic] +// CHECK:STDOUT: %C.2: type = class_type @C, @C(%T) [symbolic] +// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0 [symbolic] +// CHECK:STDOUT: %C.3: type = class_type @C, @C(%i32) [template] +// CHECK:STDOUT: %.4: type = struct_type {.x: %i32} [template] +// CHECK:STDOUT: %.5: = complete_type_witness %.4 [template] +// CHECK:STDOUT: %.6: type = unbound_element_type %C.2, %T [symbolic] +// CHECK:STDOUT: %.7: type = unbound_element_type %C.3, %i32 [template] +// CHECK:STDOUT: %Int.type: type = fn_type @Int [template] +// CHECK:STDOUT: %Int: %Int.type = struct_value () [template] +// CHECK:STDOUT: %ImportedAccess.type: type = fn_type @ImportedAccess [template] +// CHECK:STDOUT: %ImportedAccess: %ImportedAccess.type = struct_value () [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %import_ref.1: %C.type = import_ref Main//adapt_specific_type, inst+9, loaded [template = constants.%C.1] +// CHECK:STDOUT: %import_ref.2: type = import_ref Main//adapt_specific_type, inst+26, loaded [template = constants.%Adapter] +// CHECK:STDOUT: %import_ref.3 = import_ref Main//adapt_specific_type, inst+69, unloaded +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { +// CHECK:STDOUT: .Int = %import_ref.8 +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.4 = import_ref Main//adapt_specific_type, inst+15, unloaded +// CHECK:STDOUT: %import_ref.5: @C.%.1 (%.6) = import_ref Main//adapt_specific_type, inst+18, loaded [template = %.1] +// CHECK:STDOUT: %import_ref.7 = import_ref Main//adapt_specific_type, inst+27, unloaded +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = imports.%import_ref.1 +// CHECK:STDOUT: .Adapter = imports.%import_ref.2 +// CHECK:STDOUT: .Access = imports.%import_ref.3 +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .ImportedAccess = %ImportedAccess.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %default.import = import +// CHECK:STDOUT: %ImportedAccess.decl: %ImportedAccess.type = fn_decl @ImportedAccess [template = constants.%ImportedAccess] { +// CHECK:STDOUT: %a.patt: %Adapter = binding_pattern a +// CHECK:STDOUT: %a.param_patt: %Adapter = value_param_pattern %a.patt, runtime_param0 +// CHECK:STDOUT: %return.patt: %i32 = return_slot_pattern +// CHECK:STDOUT: %return.param_patt: %i32 = out_param_pattern %return.patt, runtime_param1 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %Adapter.ref: type = name_ref Adapter, imports.%import_ref.2 [template = constants.%Adapter] +// CHECK:STDOUT: %.loc6_34.1: Core.IntLiteral = int_value 32 [template = constants.%.1] +// CHECK:STDOUT: %int.make_type_signed.loc6: init type = call constants.%Int(%.loc6_34.1) [template = constants.%i32] +// CHECK:STDOUT: %.loc6_34.2: type = value_of_initializer %int.make_type_signed.loc6 [template = constants.%i32] +// CHECK:STDOUT: %.loc6_34.3: type = converted %int.make_type_signed.loc6, %.loc6_34.2 [template = constants.%i32] +// CHECK:STDOUT: %a.param: %Adapter = value_param runtime_param0 +// CHECK:STDOUT: %a: %Adapter = bind_name a, %a.param +// CHECK:STDOUT: %return.param: ref %i32 = out_param runtime_param1 +// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Adapter { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = imports.%import_ref.7 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic class @C(constants.%T: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt (constants.%T.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C: type = class_type @C, @C(%T) [symbolic = %C (constants.%C.2)] +// CHECK:STDOUT: %.1: type = unbound_element_type @C.%C (%C.2), @C.%T (%T) [symbolic = %.1 (constants.%.6)] +// CHECK:STDOUT: %.2: type = struct_type {.x: @C.%T (%T)} [symbolic = %.2 (constants.%.2)] +// CHECK:STDOUT: %.3: = complete_type_witness @C.%.2 (%.2) [symbolic = %.3 (constants.%.3)] +// CHECK:STDOUT: +// CHECK:STDOUT: class { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = imports.%import_ref.4 +// CHECK:STDOUT: .x = imports.%import_ref.5 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @ImportedAccess(%a.param_patt: %Adapter) -> %i32 { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %a.ref: %Adapter = name_ref a, %a +// CHECK:STDOUT: %C.ref: %C.type = name_ref C, imports.%import_ref.1 [template = constants.%C.1] +// CHECK:STDOUT: %.loc7_18: Core.IntLiteral = int_value 32 [template = constants.%.1] +// CHECK:STDOUT: %int.make_type_signed.loc7: init type = call constants.%Int(%.loc7_18) [template = constants.%i32] +// CHECK:STDOUT: %.loc7_17.1: type = value_of_initializer %int.make_type_signed.loc7 [template = constants.%i32] +// CHECK:STDOUT: %.loc7_17.2: type = converted %int.make_type_signed.loc7, %.loc7_17.1 [template = constants.%i32] +// CHECK:STDOUT: %C: type = class_type @C, @C(constants.%i32) [template = constants.%C.3] +// CHECK:STDOUT: %.loc7_13.1: %C.3 = as_compatible %a.ref +// CHECK:STDOUT: %.loc7_13.2: %C.3 = converted %a.ref, %.loc7_13.1 +// CHECK:STDOUT: %x.ref: %.7 = name_ref x, imports.%import_ref.5 [template = imports.%.1] +// CHECK:STDOUT: %.loc7_23.1: ref %i32 = class_element_access %.loc7_13.2, element0 +// CHECK:STDOUT: %.loc7_23.2: %i32 = bind_value %.loc7_23.1 +// CHECK:STDOUT: return %.loc7_23.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %T.patt => constants.%T +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C(constants.%i32) { +// CHECK:STDOUT: %T => constants.%i32 +// CHECK:STDOUT: %T.patt => constants.%i32 +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C => constants.%C.3 +// CHECK:STDOUT: %.1 => constants.%.7 +// CHECK:STDOUT: %.2 => constants.%.4 +// CHECK:STDOUT: %.3 => constants.%.5 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C(%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %T.patt => constants.%T +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_todo_extend_adapt_specific_type.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] +// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0 [symbolic] +// CHECK:STDOUT: %C.type: type = generic_class_type @C [template] +// CHECK:STDOUT: %C.1: %C.type = struct_value () [template] +// CHECK:STDOUT: %C.2: type = class_type @C, @C(%T) [symbolic] +// CHECK:STDOUT: %.1: type = unbound_element_type %C.2, %T [symbolic] +// CHECK:STDOUT: %.2: type = struct_type {.x: %T} [symbolic] +// CHECK:STDOUT: %.3: = complete_type_witness %.2 [symbolic] +// CHECK:STDOUT: %Adapter: type = class_type @Adapter [template] +// CHECK:STDOUT: %.4: Core.IntLiteral = int_value 32 [template] +// CHECK:STDOUT: %Int.type: type = fn_type @Int [template] +// CHECK:STDOUT: %Int: %Int.type = struct_value () [template] +// CHECK:STDOUT: %i32: type = int_type signed, %.4 [template] +// CHECK:STDOUT: %C.3: type = class_type @C, @C(%i32) [template] +// CHECK:STDOUT: %.5: type = unbound_element_type %C.3, %i32 [template] +// CHECK:STDOUT: %.6: type = struct_type {.x: %i32} [template] +// CHECK:STDOUT: %.7: = complete_type_witness %.6 [template] +// CHECK:STDOUT: %Access.type: type = fn_type @Access [template] +// CHECK:STDOUT: %Access: %Access.type = struct_value () [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { +// CHECK:STDOUT: .Int = %import_ref.1 +// CHECK:STDOUT: .ImplicitAs = %import_ref.2 +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .Adapter = %Adapter.decl +// CHECK:STDOUT: .Access = %Access.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %C.decl: %C.type = class_decl @C [template = constants.%C.1] { +// CHECK:STDOUT: %T.patt.loc4_9.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_9.2 (constants.%T.patt)] +// CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc4_9.1, runtime_param [symbolic = %T.patt.loc4_9.2 (constants.%T.patt)] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %T.param: type = value_param runtime_param +// CHECK:STDOUT: %T.loc4_9.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc4_9.2 (constants.%T)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %Adapter.decl: type = class_decl @Adapter [template = constants.%Adapter] {} {} +// CHECK:STDOUT: %Access.decl: %Access.type = fn_decl @Access [template = constants.%Access] { +// CHECK:STDOUT: %a.patt: %Adapter = binding_pattern a +// CHECK:STDOUT: %a.param_patt: %Adapter = value_param_pattern %a.patt, runtime_param0 +// CHECK:STDOUT: %return.patt: %C.3 = return_slot_pattern +// CHECK:STDOUT: %return.param_patt: %C.3 = out_param_pattern %return.patt, runtime_param1 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %Adapter.ref: type = name_ref Adapter, file.%Adapter.decl [template = constants.%Adapter] +// CHECK:STDOUT: %C.ref: %C.type = name_ref C, file.%C.decl [template = constants.%C.1] +// CHECK:STDOUT: %.loc12_28: Core.IntLiteral = int_value 32 [template = constants.%.4] +// CHECK:STDOUT: %int.make_type_signed: init type = call constants.%Int(%.loc12_28) [template = constants.%i32] +// CHECK:STDOUT: %.loc12_27.1: type = value_of_initializer %int.make_type_signed [template = constants.%i32] +// CHECK:STDOUT: %.loc12_27.2: type = converted %int.make_type_signed, %.loc12_27.1 [template = constants.%i32] +// CHECK:STDOUT: %C: type = class_type @C, @C(constants.%i32) [template = constants.%C.3] +// CHECK:STDOUT: %a.param: %Adapter = value_param runtime_param0 +// CHECK:STDOUT: %a: %Adapter = bind_name a, %a.param +// CHECK:STDOUT: %return.param: ref %C.3 = out_param runtime_param1 +// CHECK:STDOUT: %return: ref %C.3 = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic class @C(%T.loc4_9.1: type) { +// CHECK:STDOUT: %T.loc4_9.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_9.2 (constants.%T)] +// CHECK:STDOUT: %T.patt.loc4_9.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_9.2 (constants.%T.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C: type = class_type @C, @C(%T.loc4_9.2) [symbolic = %C (constants.%C.2)] +// CHECK:STDOUT: %.loc5_8.2: type = unbound_element_type @C.%C (%C.2), @C.%T.loc4_9.2 (%T) [symbolic = %.loc5_8.2 (constants.%.1)] +// CHECK:STDOUT: %.loc6_1.2: type = struct_type {.x: @C.%T.loc4_9.2 (%T)} [symbolic = %.loc6_1.2 (constants.%.2)] +// CHECK:STDOUT: %.loc6_1.3: = complete_type_witness @C.%.loc6_1.2 (%.2) [symbolic = %.loc6_1.3 (constants.%.3)] +// CHECK:STDOUT: +// CHECK:STDOUT: class { +// CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc4_9.1 [symbolic = %T.loc4_9.2 (constants.%T)] +// CHECK:STDOUT: %.loc5_8.1: @C.%.loc5_8.2 (%.1) = field_decl x, element0 [template] +// CHECK:STDOUT: %.loc6_1.1: = complete_type_witness %.2 [symbolic = %.loc6_1.3 (constants.%.3)] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C.2 +// CHECK:STDOUT: .x = %.loc5_8.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Adapter { +// CHECK:STDOUT: %C.ref: %C.type = name_ref C, file.%C.decl [template = constants.%C.1] +// CHECK:STDOUT: %.loc9_18: Core.IntLiteral = int_value 32 [template = constants.%.4] +// CHECK:STDOUT: %int.make_type_signed: init type = call constants.%Int(%.loc9_18) [template = constants.%i32] +// CHECK:STDOUT: %.loc9_17.1: type = value_of_initializer %int.make_type_signed [template = constants.%i32] +// CHECK:STDOUT: %.loc9_17.2: type = converted %int.make_type_signed, %.loc9_17.1 [template = constants.%i32] +// CHECK:STDOUT: %C: type = class_type @C, @C(constants.%i32) [template = constants.%C.3] +// CHECK:STDOUT: adapt_decl %C [template] +// CHECK:STDOUT: %.loc10: = complete_type_witness %.6 [template = constants.%.7] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%Adapter +// CHECK:STDOUT: extend %C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Access(%a.param_patt: %Adapter) -> %return: %C.3 { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %a.ref: %Adapter = name_ref a, %a +// CHECK:STDOUT: %x.ref: %.5 = name_ref x, @C.%.loc5_8.1 [template = @C.%.loc5_8.1] +// CHECK:STDOUT: %.loc27_11.1: %C.3 = converted %a.ref, [template = ] +// CHECK:STDOUT: %.loc27_11.2: %i32 = class_element_access , element0 [template = ] +// CHECK:STDOUT: %.loc27_13: %C.3 = converted %.loc27_11.2, [template = ] +// CHECK:STDOUT: return to %return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C(constants.%T) { +// CHECK:STDOUT: %T.loc4_9.2 => constants.%T +// CHECK:STDOUT: %T.patt.loc4_9.2 => constants.%T +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C(%T.loc4_9.2) { +// CHECK:STDOUT: %T.loc4_9.2 => constants.%T +// CHECK:STDOUT: %T.patt.loc4_9.2 => constants.%T +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C(constants.%i32) { +// CHECK:STDOUT: %T.loc4_9.2 => constants.%i32 +// CHECK:STDOUT: %T.patt.loc4_9.2 => constants.%i32 +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C => constants.%C.3 +// CHECK:STDOUT: %.loc5_8.2 => constants.%.5 +// CHECK:STDOUT: %.loc6_1.2 => constants.%.6 +// CHECK:STDOUT: %.loc6_1.3 => constants.%.7 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_todo_import_extend_adapt_specific_type.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %Adapter: type = class_type @Adapter [template] +// CHECK:STDOUT: %.1: Core.IntLiteral = int_value 32 [template] +// CHECK:STDOUT: %i32: type = int_type signed, %.1 [template] +// CHECK:STDOUT: %C.type: type = generic_class_type @C [template] +// CHECK:STDOUT: %C.1: %C.type = struct_value () [template] +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] +// CHECK:STDOUT: %.2: type = struct_type {.x: %T} [symbolic] +// CHECK:STDOUT: %.3: = complete_type_witness %.2 [symbolic] +// CHECK:STDOUT: %C.2: type = class_type @C, @C(%T) [symbolic] +// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0 [symbolic] +// CHECK:STDOUT: %C.3: type = class_type @C, @C(%i32) [template] +// CHECK:STDOUT: %.4: type = struct_type {.x: %i32} [template] +// CHECK:STDOUT: %.5: = complete_type_witness %.4 [template] +// CHECK:STDOUT: %.6: type = unbound_element_type %C.2, %T [symbolic] +// CHECK:STDOUT: %.7: type = unbound_element_type %C.3, %i32 [template] +// CHECK:STDOUT: %Int.type: type = fn_type @Int [template] +// CHECK:STDOUT: %Int: %Int.type = struct_value () [template] +// CHECK:STDOUT: %ImportedAccess.type: type = fn_type @ImportedAccess [template] +// CHECK:STDOUT: %ImportedAccess: %ImportedAccess.type = struct_value () [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %import_ref.1: %C.type = import_ref Main//adapt_specific_type, inst+9, loaded [template = constants.%C.1] +// CHECK:STDOUT: %import_ref.2: type = import_ref Main//adapt_specific_type, inst+26, loaded [template = constants.%Adapter] +// CHECK:STDOUT: %import_ref.3 = import_ref Main//adapt_specific_type, inst+69, unloaded +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { +// CHECK:STDOUT: .Int = %import_ref.8 +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.4 = import_ref Main//adapt_specific_type, inst+15, unloaded +// CHECK:STDOUT: %import_ref.5: @C.%.1 (%.6) = import_ref Main//adapt_specific_type, inst+18, loaded [template = %.1] +// CHECK:STDOUT: %import_ref.7 = import_ref Main//adapt_specific_type, inst+27, unloaded +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = imports.%import_ref.1 +// CHECK:STDOUT: .Adapter = imports.%import_ref.2 +// CHECK:STDOUT: .Access = imports.%import_ref.3 +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .ImportedAccess = %ImportedAccess.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %default.import = import +// CHECK:STDOUT: %ImportedAccess.decl: %ImportedAccess.type = fn_decl @ImportedAccess [template = constants.%ImportedAccess] { +// CHECK:STDOUT: %a.patt: %Adapter = binding_pattern a +// CHECK:STDOUT: %a.param_patt: %Adapter = value_param_pattern %a.patt, runtime_param0 +// CHECK:STDOUT: %return.patt: %i32 = return_slot_pattern +// CHECK:STDOUT: %return.param_patt: %i32 = out_param_pattern %return.patt, runtime_param1 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %Adapter.ref: type = name_ref Adapter, imports.%import_ref.2 [template = constants.%Adapter] +// CHECK:STDOUT: %.loc6_34.1: Core.IntLiteral = int_value 32 [template = constants.%.1] +// CHECK:STDOUT: %int.make_type_signed.loc6: init type = call constants.%Int(%.loc6_34.1) [template = constants.%i32] +// CHECK:STDOUT: %.loc6_34.2: type = value_of_initializer %int.make_type_signed.loc6 [template = constants.%i32] +// CHECK:STDOUT: %.loc6_34.3: type = converted %int.make_type_signed.loc6, %.loc6_34.2 [template = constants.%i32] +// CHECK:STDOUT: %a.param: %Adapter = value_param runtime_param0 +// CHECK:STDOUT: %a: %Adapter = bind_name a, %a.param +// CHECK:STDOUT: %return.param: ref %i32 = out_param runtime_param1 +// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Adapter { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = imports.%import_ref.7 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic class @C(constants.%T: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt (constants.%T.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C: type = class_type @C, @C(%T) [symbolic = %C (constants.%C.2)] +// CHECK:STDOUT: %.1: type = unbound_element_type @C.%C (%C.2), @C.%T (%T) [symbolic = %.1 (constants.%.6)] +// CHECK:STDOUT: %.2: type = struct_type {.x: @C.%T (%T)} [symbolic = %.2 (constants.%.2)] +// CHECK:STDOUT: %.3: = complete_type_witness @C.%.2 (%.2) [symbolic = %.3 (constants.%.3)] +// CHECK:STDOUT: +// CHECK:STDOUT: class { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = imports.%import_ref.4 +// CHECK:STDOUT: .x = imports.%import_ref.5 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @ImportedAccess(%a.param_patt: %Adapter) -> %i32 { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %a.ref: %Adapter = name_ref a, %a +// CHECK:STDOUT: %C.ref: %C.type = name_ref C, imports.%import_ref.1 [template = constants.%C.1] +// CHECK:STDOUT: %.loc8_18: Core.IntLiteral = int_value 32 [template = constants.%.1] +// CHECK:STDOUT: %int.make_type_signed.loc8: init type = call constants.%Int(%.loc8_18) [template = constants.%i32] +// CHECK:STDOUT: %.loc8_17.1: type = value_of_initializer %int.make_type_signed.loc8 [template = constants.%i32] +// CHECK:STDOUT: %.loc8_17.2: type = converted %int.make_type_signed.loc8, %.loc8_17.1 [template = constants.%i32] +// CHECK:STDOUT: %C: type = class_type @C, @C(constants.%i32) [template = constants.%C.3] +// CHECK:STDOUT: %.loc8_13.1: %C.3 = as_compatible %a.ref +// CHECK:STDOUT: %.loc8_13.2: %C.3 = converted %a.ref, %.loc8_13.1 +// CHECK:STDOUT: %x.ref: %.7 = name_ref x, imports.%import_ref.5 [template = imports.%.1] +// CHECK:STDOUT: %.loc8_23.1: ref %i32 = class_element_access %.loc8_13.2, element0 +// CHECK:STDOUT: %.loc8_23.2: %i32 = bind_value %.loc8_23.1 +// CHECK:STDOUT: return %.loc8_23.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %T.patt => constants.%T +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C(constants.%i32) { +// CHECK:STDOUT: %T => constants.%i32 +// CHECK:STDOUT: %T.patt => constants.%i32 +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C => constants.%C.3 +// CHECK:STDOUT: %.1 => constants.%.7 +// CHECK:STDOUT: %.2 => constants.%.4 +// CHECK:STDOUT: %.3 => constants.%.5 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C(%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %T.patt => constants.%T +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- adapt_generic_type.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] +// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0 [symbolic] +// CHECK:STDOUT: %Adapter.type: type = generic_class_type @Adapter [template] +// CHECK:STDOUT: %Adapter.1: %Adapter.type = struct_value () [template] +// CHECK:STDOUT: %Adapter.2: type = class_type @Adapter, @Adapter(%T) [symbolic] +// CHECK:STDOUT: %.1: = complete_type_witness %T [symbolic] +// CHECK:STDOUT: %.2: Core.IntLiteral = int_value 32 [template] +// CHECK:STDOUT: %Int.type: type = fn_type @Int [template] +// CHECK:STDOUT: %Int: %Int.type = struct_value () [template] +// CHECK:STDOUT: %i32: type = int_type signed, %.2 [template] +// CHECK:STDOUT: %Adapter.3: type = class_type @Adapter, @Adapter(%i32) [template] +// CHECK:STDOUT: %Convert.type: type = fn_type @Convert [template] +// CHECK:STDOUT: %Convert: %Convert.type = struct_value () [template] +// CHECK:STDOUT: %.3: = complete_type_witness %i32 [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { +// CHECK:STDOUT: .Int = %import_ref +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .Adapter = %Adapter.decl +// CHECK:STDOUT: .Convert = %Convert.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %Adapter.decl: %Adapter.type = class_decl @Adapter [template = constants.%Adapter.1] { +// CHECK:STDOUT: %T.patt.loc4_15.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_15.2 (constants.%T.patt)] +// CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc4_15.1, runtime_param [symbolic = %T.patt.loc4_15.2 (constants.%T.patt)] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %T.param: type = value_param runtime_param +// CHECK:STDOUT: %T.loc4_15.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc4_15.2 (constants.%T)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %Convert.decl: %Convert.type = fn_decl @Convert [template = constants.%Convert] { +// CHECK:STDOUT: %a.patt: %Adapter.3 = binding_pattern a +// CHECK:STDOUT: %a.param_patt: %Adapter.3 = value_param_pattern %a.patt, runtime_param0 +// CHECK:STDOUT: %return.patt: %i32 = return_slot_pattern +// CHECK:STDOUT: %return.param_patt: %i32 = out_param_pattern %return.patt, runtime_param1 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %Adapter.ref: %Adapter.type = name_ref Adapter, file.%Adapter.decl [template = constants.%Adapter.1] +// CHECK:STDOUT: %.loc8_23: Core.IntLiteral = int_value 32 [template = constants.%.2] +// CHECK:STDOUT: %int.make_type_signed.loc8_23: init type = call constants.%Int(%.loc8_23) [template = constants.%i32] +// CHECK:STDOUT: %.loc8_22.1: type = value_of_initializer %int.make_type_signed.loc8_23 [template = constants.%i32] +// CHECK:STDOUT: %.loc8_22.2: type = converted %int.make_type_signed.loc8_23, %.loc8_22.1 [template = constants.%i32] +// CHECK:STDOUT: %Adapter: type = class_type @Adapter, @Adapter(constants.%i32) [template = constants.%Adapter.3] +// CHECK:STDOUT: %.loc8_32.1: Core.IntLiteral = int_value 32 [template = constants.%.2] +// CHECK:STDOUT: %int.make_type_signed.loc8_32: init type = call constants.%Int(%.loc8_32.1) [template = constants.%i32] +// CHECK:STDOUT: %.loc8_32.2: type = value_of_initializer %int.make_type_signed.loc8_32 [template = constants.%i32] +// CHECK:STDOUT: %.loc8_32.3: type = converted %int.make_type_signed.loc8_32, %.loc8_32.2 [template = constants.%i32] +// CHECK:STDOUT: %a.param: %Adapter.3 = value_param runtime_param0 +// CHECK:STDOUT: %a: %Adapter.3 = bind_name a, %a.param +// CHECK:STDOUT: %return.param: ref %i32 = out_param runtime_param1 +// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic class @Adapter(%T.loc4_15.1: type) { +// CHECK:STDOUT: %T.loc4_15.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_15.2 (constants.%T)] +// CHECK:STDOUT: %T.patt.loc4_15.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_15.2 (constants.%T.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %.loc6_1.2: = complete_type_witness @Adapter.%T.loc4_15.2 (%T) [symbolic = %.loc6_1.2 (constants.%.1)] +// CHECK:STDOUT: +// CHECK:STDOUT: class { +// CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc4_15.1 [symbolic = %T.loc4_15.2 (constants.%T)] +// CHECK:STDOUT: adapt_decl %T.ref [template] +// CHECK:STDOUT: %.loc6_1.1: = complete_type_witness %T [symbolic = %.loc6_1.2 (constants.%.1)] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%Adapter.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Convert(%a.param_patt: %Adapter.3) -> %i32 { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %a.ref: %Adapter.3 = name_ref a, %a +// CHECK:STDOUT: %.loc9_15.1: Core.IntLiteral = int_value 32 [template = constants.%.2] +// CHECK:STDOUT: %int.make_type_signed.loc9: init type = call constants.%Int(%.loc9_15.1) [template = constants.%i32] +// CHECK:STDOUT: %.loc9_15.2: type = value_of_initializer %int.make_type_signed.loc9 [template = constants.%i32] +// CHECK:STDOUT: %.loc9_15.3: type = converted %int.make_type_signed.loc9, %.loc9_15.2 [template = constants.%i32] +// CHECK:STDOUT: %.loc9_12.1: %i32 = as_compatible %a.ref +// CHECK:STDOUT: %.loc9_12.2: %i32 = converted %a.ref, %.loc9_12.1 +// CHECK:STDOUT: return %.loc9_12.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Adapter(constants.%T) { +// CHECK:STDOUT: %T.loc4_15.2 => constants.%T +// CHECK:STDOUT: %T.patt.loc4_15.2 => constants.%T +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Adapter(constants.%i32) { +// CHECK:STDOUT: %T.loc4_15.2 => constants.%i32 +// CHECK:STDOUT: %T.patt.loc4_15.2 => constants.%i32 +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %.loc6_1.2 => constants.%.3 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- import_adapt_generic_type.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %Adapter.type: type = generic_class_type @Adapter [template] +// CHECK:STDOUT: %Adapter.1: %Adapter.type = struct_value () [template] +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] +// CHECK:STDOUT: %.1: = complete_type_witness %T [symbolic] +// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0 [symbolic] +// CHECK:STDOUT: %.2: Core.IntLiteral = int_value 32 [template] +// CHECK:STDOUT: %Int.type: type = fn_type @Int [template] +// CHECK:STDOUT: %Int: %Int.type = struct_value () [template] +// CHECK:STDOUT: %i32: type = int_type signed, %.2 [template] +// CHECK:STDOUT: %Adapter.3: type = class_type @Adapter, @Adapter(%i32) [template] +// CHECK:STDOUT: %ImportedConvert.type: type = fn_type @ImportedConvert [template] +// CHECK:STDOUT: %ImportedConvert: %ImportedConvert.type = struct_value () [template] +// CHECK:STDOUT: %.3: = complete_type_witness %i32 [template] +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.4: type = unbound_element_type %C, %i32 [template] +// CHECK:STDOUT: %.5: type = struct_type {.n: %i32} [template] +// CHECK:STDOUT: %.6: = complete_type_witness %.5 [template] +// CHECK:STDOUT: %Adapter.4: type = class_type @Adapter, @Adapter(%C) [template] +// CHECK:STDOUT: %ImportedConvertLocal.type: type = fn_type @ImportedConvertLocal [template] +// CHECK:STDOUT: %ImportedConvertLocal: %ImportedConvertLocal.type = struct_value () [template] +// CHECK:STDOUT: %.7: = complete_type_witness %C [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %import_ref.1: %Adapter.type = import_ref Main//adapt_generic_type, inst+9, loaded [template = constants.%Adapter.1] +// CHECK:STDOUT: %import_ref.2 = import_ref Main//adapt_generic_type, inst+53, unloaded +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { +// CHECK:STDOUT: .Int = %import_ref.5 +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.4 = import_ref Main//adapt_generic_type, inst+15, unloaded +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .Adapter = imports.%import_ref.1 +// CHECK:STDOUT: .Convert = imports.%import_ref.2 +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .ImportedConvert = %ImportedConvert.decl +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .ImportedConvertLocal = %ImportedConvertLocal.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %default.import = import +// CHECK:STDOUT: %ImportedConvert.decl: %ImportedConvert.type = fn_decl @ImportedConvert [template = constants.%ImportedConvert] { +// CHECK:STDOUT: %a.patt: %Adapter.3 = binding_pattern a +// CHECK:STDOUT: %a.param_patt: %Adapter.3 = value_param_pattern %a.patt, runtime_param0 +// CHECK:STDOUT: %return.patt: %i32 = return_slot_pattern +// CHECK:STDOUT: %return.param_patt: %i32 = out_param_pattern %return.patt, runtime_param1 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %Adapter.ref: %Adapter.type = name_ref Adapter, imports.%import_ref.1 [template = constants.%Adapter.1] +// CHECK:STDOUT: %.loc6_31: Core.IntLiteral = int_value 32 [template = constants.%.2] +// CHECK:STDOUT: %int.make_type_signed.loc6_31: init type = call constants.%Int(%.loc6_31) [template = constants.%i32] +// CHECK:STDOUT: %.loc6_30.1: type = value_of_initializer %int.make_type_signed.loc6_31 [template = constants.%i32] +// CHECK:STDOUT: %.loc6_30.2: type = converted %int.make_type_signed.loc6_31, %.loc6_30.1 [template = constants.%i32] +// CHECK:STDOUT: %Adapter: type = class_type @Adapter, @Adapter(constants.%i32) [template = constants.%Adapter.3] +// CHECK:STDOUT: %.loc6_40.1: Core.IntLiteral = int_value 32 [template = constants.%.2] +// CHECK:STDOUT: %int.make_type_signed.loc6_40: init type = call constants.%Int(%.loc6_40.1) [template = constants.%i32] +// CHECK:STDOUT: %.loc6_40.2: type = value_of_initializer %int.make_type_signed.loc6_40 [template = constants.%i32] +// CHECK:STDOUT: %.loc6_40.3: type = converted %int.make_type_signed.loc6_40, %.loc6_40.2 [template = constants.%i32] +// CHECK:STDOUT: %a.param: %Adapter.3 = value_param runtime_param0 +// CHECK:STDOUT: %a: %Adapter.3 = bind_name a, %a.param +// CHECK:STDOUT: %return.param: ref %i32 = out_param runtime_param1 +// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} {} +// CHECK:STDOUT: %ImportedConvertLocal.decl: %ImportedConvertLocal.type = fn_decl @ImportedConvertLocal [template = constants.%ImportedConvertLocal] { +// CHECK:STDOUT: %a.patt: %Adapter.4 = binding_pattern a +// CHECK:STDOUT: %a.param_patt: %Adapter.4 = value_param_pattern %a.patt, runtime_param0 +// CHECK:STDOUT: %return.patt: %i32 = return_slot_pattern +// CHECK:STDOUT: %return.param_patt: %i32 = out_param_pattern %return.patt, runtime_param1 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %Adapter.ref: %Adapter.type = name_ref Adapter, imports.%import_ref.1 [template = constants.%Adapter.1] +// CHECK:STDOUT: %C.ref.loc14: type = name_ref C, file.%C.decl [template = constants.%C] +// CHECK:STDOUT: %Adapter: type = class_type @Adapter, @Adapter(constants.%C) [template = constants.%Adapter.4] +// CHECK:STDOUT: %.loc14_43.1: Core.IntLiteral = int_value 32 [template = constants.%.2] +// CHECK:STDOUT: %int.make_type_signed: init type = call constants.%Int(%.loc14_43.1) [template = constants.%i32] +// CHECK:STDOUT: %.loc14_43.2: type = value_of_initializer %int.make_type_signed [template = constants.%i32] +// CHECK:STDOUT: %.loc14_43.3: type = converted %int.make_type_signed, %.loc14_43.2 [template = constants.%i32] +// CHECK:STDOUT: %a.param: %Adapter.4 = value_param runtime_param0 +// CHECK:STDOUT: %a: %Adapter.4 = bind_name a, %a.param +// CHECK:STDOUT: %return.param: ref %i32 = out_param runtime_param1 +// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic class @Adapter(constants.%T: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt (constants.%T.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %.1: = complete_type_witness @Adapter.%T (%T) [symbolic = %.1 (constants.%.1)] +// CHECK:STDOUT: +// CHECK:STDOUT: class { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = imports.%import_ref.4 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: %.loc11_10.1: Core.IntLiteral = int_value 32 [template = constants.%.2] +// CHECK:STDOUT: %int.make_type_signed: init type = call constants.%Int(%.loc11_10.1) [template = constants.%i32] +// CHECK:STDOUT: %.loc11_10.2: type = value_of_initializer %int.make_type_signed [template = constants.%i32] +// CHECK:STDOUT: %.loc11_10.3: type = converted %int.make_type_signed, %.loc11_10.2 [template = constants.%i32] +// CHECK:STDOUT: %.loc11_8: %.4 = field_decl n, element0 [template] +// CHECK:STDOUT: %.loc12: = complete_type_witness %.5 [template = constants.%.6] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: .n = %.loc11_8 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @ImportedConvert(%a.param_patt: %Adapter.3) -> %i32 { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %a.ref: %Adapter.3 = name_ref a, %a +// CHECK:STDOUT: %.loc7_15.1: Core.IntLiteral = int_value 32 [template = constants.%.2] +// CHECK:STDOUT: %int.make_type_signed.loc7: init type = call constants.%Int(%.loc7_15.1) [template = constants.%i32] +// CHECK:STDOUT: %.loc7_15.2: type = value_of_initializer %int.make_type_signed.loc7 [template = constants.%i32] +// CHECK:STDOUT: %.loc7_15.3: type = converted %int.make_type_signed.loc7, %.loc7_15.2 [template = constants.%i32] +// CHECK:STDOUT: %.loc7_12.1: %i32 = as_compatible %a.ref +// CHECK:STDOUT: %.loc7_12.2: %i32 = converted %a.ref, %.loc7_12.1 +// CHECK:STDOUT: return %.loc7_12.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @ImportedConvertLocal(%a.param_patt: %Adapter.4) -> %i32 { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %a.ref: %Adapter.4 = name_ref a, %a +// CHECK:STDOUT: %C.ref.loc15: type = name_ref C, file.%C.decl [template = constants.%C] +// CHECK:STDOUT: %.loc15_13.1: %C = as_compatible %a.ref +// CHECK:STDOUT: %.loc15_13.2: %C = converted %a.ref, %.loc15_13.1 +// CHECK:STDOUT: %n.ref: %.4 = name_ref n, @C.%.loc11_8 [template = @C.%.loc11_8] +// CHECK:STDOUT: %.loc15_18.1: ref %i32 = class_element_access %.loc15_13.2, element0 +// CHECK:STDOUT: %.loc15_18.2: %i32 = bind_value %.loc15_18.1 +// CHECK:STDOUT: return %.loc15_18.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Adapter(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %T.patt => constants.%T +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Adapter(constants.%i32) { +// CHECK:STDOUT: %T => constants.%i32 +// CHECK:STDOUT: %T.patt => constants.%i32 +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %.1 => constants.%.3 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Adapter(constants.%C) { +// CHECK:STDOUT: %T => constants.%C +// CHECK:STDOUT: %T.patt => constants.%C +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %.1 => constants.%.7 +// CHECK:STDOUT: } +// CHECK:STDOUT: From ecd787e39433c179016f720e8b9c1b640f9b620a Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Thu, 21 Nov 2024 21:59:18 +0000 Subject: [PATCH 05/11] clang-format --- toolchain/check/handle_class.cpp | 3 +-- toolchain/check/import_ref.cpp | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/toolchain/check/handle_class.cpp b/toolchain/check/handle_class.cpp index eadf80aa6ad80..d91400eed5b1a 100644 --- a/toolchain/check/handle_class.cpp +++ b/toolchain/check/handle_class.cpp @@ -394,8 +394,7 @@ auto HandleParseNode(Context& context, Parse::AdaptDeclId node_id) -> bool { }, [&] { CARBON_DIAGNOSTIC(AbstractTypeInAdaptDecl, Error, - "adapted type {0} is an abstract type", - InstIdAsType); + "adapted type {0} is an abstract type", InstIdAsType); return context.emitter().Build(node_id, AbstractTypeInAdaptDecl, adapted_inst_id); }); diff --git a/toolchain/check/import_ref.cpp b/toolchain/check/import_ref.cpp index 6a3189e269f3e..7f959aac8331f 100644 --- a/toolchain/check/import_ref.cpp +++ b/toolchain/check/import_ref.cpp @@ -1481,8 +1481,8 @@ class ImportRefResolver { auto AddClassDefinition(const SemIR::Class& import_class, SemIR::Class& new_class, SemIR::InstId complete_type_witness_id, - SemIR::InstId base_id, - SemIR::InstId adapt_id) -> void { + SemIR::InstId base_id, SemIR::InstId adapt_id) + -> void { new_class.definition_id = new_class.first_owning_decl_id; new_class.complete_type_witness_id = complete_type_witness_id; From 79c0d6bb7e60294b3296360a727f2b1967da821d Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Sat, 23 Nov 2024 00:08:20 +0000 Subject: [PATCH 06/11] Improve comments. --- toolchain/lower/constant.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/toolchain/lower/constant.cpp b/toolchain/lower/constant.cpp index a4cba1882101b..7dc55d9c816f4 100644 --- a/toolchain/lower/constant.cpp +++ b/toolchain/lower/constant.cpp @@ -209,6 +209,9 @@ static auto EmitAsConstant(ConstantContext& /*context*/, CARBON_FATAL("TODO: Add support: {0}", inst); } +// Tries to emit an LLVM constant value for this constant instruction. Centrally +// handles some common cases and then dispatches to the relevant EmitAsConstant +// overload based on the type of the instruction for the remaining cases. template static auto MaybeEmitAsConstant(ConstantContext& context, InstT inst) -> llvm::Constant* { @@ -221,6 +224,7 @@ static auto MaybeEmitAsConstant(ConstantContext& context, InstT inst) // be used by lowering. return nullptr; } else if constexpr (InstT::Kind.is_type() == SemIR::InstIsType::Always) { + // All types are lowered to the same value. return context.GetTypeAsValue(); } else { return EmitAsConstant(context, inst); From d2abf71ba5c9d6d4d93eda79261c2ea7d9ba6bb3 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Sat, 23 Nov 2024 00:20:29 +0000 Subject: [PATCH 07/11] Simplify. Co-authored-by: Jon Ross-Perkins --- toolchain/check/handle_class.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/toolchain/check/handle_class.cpp b/toolchain/check/handle_class.cpp index d91400eed5b1a..7c0792986c727 100644 --- a/toolchain/check/handle_class.cpp +++ b/toolchain/check/handle_class.cpp @@ -645,9 +645,9 @@ static auto CheckCompleteClassType(Context& context, Parse::NodeId node_id, } bool defining_vtable_ptr = class_info.is_dynamic; - if (class_info.base_id.is_valid()) { - auto base_type_id = - class_info.GetBaseType(context.sem_ir(), SemIR::SpecificId::Invalid); + if (auto base_type_id = + class_info.GetBaseType(context.sem_ir(), SemIR::SpecificId::Invalid); + base_type_id.is_valid()) { // TODO: If the base class is template dependent, we will need to decide // whether to add a vptr as part of instantiation. if (auto* base_class_info = TryGetAsClass(context, base_type_id); From 9bb62e998f0a5ba81c25e9d7ac0b47349cd6a7b1 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Mon, 25 Nov 2024 19:05:51 +0000 Subject: [PATCH 08/11] Factor out shared handling of adapt and base declarations. --- toolchain/sem_ir/class.cpp | 27 ++++++++++++--------------- toolchain/sem_ir/typed_insts.h | 11 +++++++++++ 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/toolchain/sem_ir/class.cpp b/toolchain/sem_ir/class.cpp index 6602e785080ad..96008c8ea1fad 100644 --- a/toolchain/sem_ir/class.cpp +++ b/toolchain/sem_ir/class.cpp @@ -7,34 +7,31 @@ #include "toolchain/sem_ir/file.h" #include "toolchain/sem_ir/generic.h" #include "toolchain/sem_ir/ids.h" +#include "toolchain/sem_ir/typed_insts.h" namespace Carbon::SemIR { -auto Class::GetAdaptedType(const File& file, SpecificId specific_id) const - -> TypeId { - if (!adapt_id.is_valid()) { +static auto GetFoundationType(const File& file, SpecificId specific_id, + InstId inst_id) -> TypeId { + if (!inst_id.is_valid()) { return TypeId::Invalid; } - if (base_id == SemIR::InstId::BuiltinErrorInst) { + if (inst_id == SemIR::InstId::BuiltinErrorInst) { return TypeId::Error; } return TypeId::ForTypeConstant(GetConstantValueInSpecific( file, specific_id, - file.insts().GetAs(adapt_id).adapted_type_inst_id)); + file.insts().GetAs(inst_id).foundation_type_inst_id)); +} + +auto Class::GetAdaptedType(const File& file, SpecificId specific_id) const + -> TypeId { + return GetFoundationType(file, specific_id, adapt_id); } auto Class::GetBaseType(const File& file, SpecificId specific_id) const -> TypeId { - if (!base_id.is_valid()) { - return TypeId::Invalid; - } - if (base_id == SemIR::InstId::BuiltinErrorInst) { - return TypeId::Error; - } - CARBON_CHECK(base_id.index >= 0); - return TypeId::ForTypeConstant(GetConstantValueInSpecific( - file, specific_id, - file.insts().GetAs(base_id).base_type_inst_id)); + return GetFoundationType(file, specific_id, base_id); } auto Class::GetObjectRepr(const File& file, SpecificId specific_id) const diff --git a/toolchain/sem_ir/typed_insts.h b/toolchain/sem_ir/typed_insts.h index d444accfd78bf..f3aa4bb776551 100644 --- a/toolchain/sem_ir/typed_insts.h +++ b/toolchain/sem_ir/typed_insts.h @@ -59,6 +59,17 @@ namespace Carbon::SemIR { }; #include "toolchain/sem_ir/inst_kind.def" +// Common representation for declarations describing the foundation type of a +// class -- either its adapted type or its base class. +struct AnyFoundationDecl { + static constexpr InstKind Kinds[] = {InstKind::AdaptDecl, InstKind::BaseDecl}; + + InstKind kind; + InstId foundation_type_inst_id; + // Kind-specific data. + int32_t arg1; +}; + // An adapted type declaration in a class, of the form `adapt T;`. struct AdaptDecl { static constexpr auto Kind = InstKind::AdaptDecl.Define( From ce28fbf22538a82d52b1202d97b116df118c461c Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Tue, 26 Nov 2024 20:04:48 +0000 Subject: [PATCH 09/11] Fix test. --- .../check/testdata/class/generic/adapt.carbon | 269 ++++++++++++------ 1 file changed, 181 insertions(+), 88 deletions(-) diff --git a/toolchain/check/testdata/class/generic/adapt.carbon b/toolchain/check/testdata/class/generic/adapt.carbon index dab0d40c2205f..74487aa4dd727 100644 --- a/toolchain/check/testdata/class/generic/adapt.carbon +++ b/toolchain/check/testdata/class/generic/adapt.carbon @@ -20,14 +20,7 @@ class Adapter { adapt C(i32); } -fn Access(a: Adapter) -> C(i32) { - // CHECK:STDERR: adapt_specific_type.carbon:[[@LINE+7]]:3: error: cannot implicitly convert from `i32` to `C(i32)` [ImplicitAsConversionFailure] - // CHECK:STDERR: return (a as C(i32)).x; - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~ - // CHECK:STDERR: adapt_specific_type.carbon:[[@LINE+4]]:3: note: type `i32` does not implement interface `ImplicitAs(C(i32))` [MissingImplInMemberAccessNote] - // CHECK:STDERR: return (a as C(i32)).x; - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~ - // CHECK:STDERR: +fn Access(a: Adapter) -> i32 { return (a as C(i32)).x; } @@ -53,33 +46,45 @@ class Adapter { extend adapt C(i32); } -fn Access(a: Adapter) -> C(i32) { +fn Access(a: Adapter) -> i32 { // TODO: This should presumably work, but the design doesn't say how yet. - // CHECK:STDERR: fail_todo_extend_adapt_specific_type.carbon:[[@LINE+13]]:3: error: cannot implicitly convert from `i32` to `C(i32)` [ImplicitAsConversionFailure] - // CHECK:STDERR: return a.x; - // CHECK:STDERR: ^~~~~~~~~~~ - // CHECK:STDERR: fail_todo_extend_adapt_specific_type.carbon:[[@LINE+10]]:3: note: type `i32` does not implement interface `ImplicitAs(C(i32))` [MissingImplInMemberAccessNote] - // CHECK:STDERR: return a.x; - // CHECK:STDERR: ^~~~~~~~~~~ - // CHECK:STDERR: - // CHECK:STDERR: fail_todo_extend_adapt_specific_type.carbon:[[@LINE+6]]:10: error: cannot implicitly convert from `Adapter` to `C(i32)` [ImplicitAsConversionFailure] + // CHECK:STDERR: fail_todo_extend_adapt_specific_type.carbon:[[@LINE+7]]:10: error: cannot implicitly convert from `Adapter` to `C(i32)` [ImplicitAsConversionFailure] // CHECK:STDERR: return a.x; // CHECK:STDERR: ^~~ - // CHECK:STDERR: fail_todo_extend_adapt_specific_type.carbon:[[@LINE+3]]:10: note: type `Adapter` does not implement interface `ImplicitAs(C(i32))` [MissingImplInMemberAccessNote] + // CHECK:STDERR: fail_todo_extend_adapt_specific_type.carbon:[[@LINE+4]]:10: note: type `Adapter` does not implement interface `ImplicitAs(C(i32))` [MissingImplInMemberAccessNote] // CHECK:STDERR: return a.x; // CHECK:STDERR: ^~~ + // CHECK:STDERR: return a.x; } +// --- extend_adapt_specific_type_copy.carbon + +library "[[@TEST_NAME]]"; + +class C(T:! type) { + var x: T; +} + +class Adapter { + extend adapt C(i32); +} + // --- fail_todo_import_extend_adapt_specific_type.carbon library "[[@TEST_NAME]]"; -import library "adapt_specific_type"; +import library "extend_adapt_specific_type_copy"; fn ImportedAccess(a: Adapter) -> i32 { // TODO: This should presumably work, but the design doesn't say how yet. - return (a as C(i32)).x; + // CHECK:STDERR: fail_todo_import_extend_adapt_specific_type.carbon:[[@LINE+6]]:10: error: cannot implicitly convert from `Adapter` to `C(i32)` [ImplicitAsConversionFailure] + // CHECK:STDERR: return a.x; + // CHECK:STDERR: ^~~ + // CHECK:STDERR: fail_todo_import_extend_adapt_specific_type.carbon:[[@LINE+3]]:10: note: type `Adapter` does not implement interface `ImplicitAs(C(i32))` [MissingImplInMemberAccessNote] + // CHECK:STDERR: return a.x; + // CHECK:STDERR: ^~~ + return a.x; } // --- adapt_generic_type.carbon @@ -138,8 +143,7 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { -// CHECK:STDOUT: .Int = %import_ref.1 -// CHECK:STDOUT: .ImplicitAs = %import_ref.2 +// CHECK:STDOUT: .Int = %import_ref // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } @@ -164,20 +168,18 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: %Access.decl: %Access.type = fn_decl @Access [template = constants.%Access] { // CHECK:STDOUT: %a.patt: %Adapter = binding_pattern a // CHECK:STDOUT: %a.param_patt: %Adapter = value_param_pattern %a.patt, runtime_param0 -// CHECK:STDOUT: %return.patt: %C.3 = return_slot_pattern -// CHECK:STDOUT: %return.param_patt: %C.3 = out_param_pattern %return.patt, runtime_param1 +// CHECK:STDOUT: %return.patt: %i32 = return_slot_pattern +// CHECK:STDOUT: %return.param_patt: %i32 = out_param_pattern %return.patt, runtime_param1 // CHECK:STDOUT: } { // CHECK:STDOUT: %Adapter.ref: type = name_ref Adapter, file.%Adapter.decl [template = constants.%Adapter] -// CHECK:STDOUT: %C.ref.loc12: %C.type = name_ref C, file.%C.decl [template = constants.%C.1] -// CHECK:STDOUT: %.loc12_28: Core.IntLiteral = int_value 32 [template = constants.%.4] -// CHECK:STDOUT: %int.make_type_signed.loc12: init type = call constants.%Int(%.loc12_28) [template = constants.%i32] -// CHECK:STDOUT: %.loc12_27.1: type = value_of_initializer %int.make_type_signed.loc12 [template = constants.%i32] -// CHECK:STDOUT: %.loc12_27.2: type = converted %int.make_type_signed.loc12, %.loc12_27.1 [template = constants.%i32] -// CHECK:STDOUT: %C.loc12: type = class_type @C, @C(constants.%i32) [template = constants.%C.3] +// CHECK:STDOUT: %.loc12_26.1: Core.IntLiteral = int_value 32 [template = constants.%.4] +// CHECK:STDOUT: %int.make_type_signed.loc12: init type = call constants.%Int(%.loc12_26.1) [template = constants.%i32] +// CHECK:STDOUT: %.loc12_26.2: type = value_of_initializer %int.make_type_signed.loc12 [template = constants.%i32] +// CHECK:STDOUT: %.loc12_26.3: type = converted %int.make_type_signed.loc12, %.loc12_26.2 [template = constants.%i32] // CHECK:STDOUT: %a.param: %Adapter = value_param runtime_param0 // CHECK:STDOUT: %a: %Adapter = bind_name a, %a.param -// CHECK:STDOUT: %return.param: ref %C.3 = out_param runtime_param1 -// CHECK:STDOUT: %return: ref %C.3 = return_slot %return.param +// CHECK:STDOUT: %return.param: ref %i32 = out_param runtime_param1 +// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: @@ -216,22 +218,21 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: .Self = constants.%Adapter // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @Access(%a.param_patt: %Adapter) -> %return: %C.3 { +// CHECK:STDOUT: fn @Access(%a.param_patt: %Adapter) -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %a.ref: %Adapter = name_ref a, %a -// CHECK:STDOUT: %C.ref.loc20: %C.type = name_ref C, file.%C.decl [template = constants.%C.1] -// CHECK:STDOUT: %.loc20_18: Core.IntLiteral = int_value 32 [template = constants.%.4] -// CHECK:STDOUT: %int.make_type_signed.loc20: init type = call constants.%Int(%.loc20_18) [template = constants.%i32] -// CHECK:STDOUT: %.loc20_17.1: type = value_of_initializer %int.make_type_signed.loc20 [template = constants.%i32] -// CHECK:STDOUT: %.loc20_17.2: type = converted %int.make_type_signed.loc20, %.loc20_17.1 [template = constants.%i32] -// CHECK:STDOUT: %C.loc20: type = class_type @C, @C(constants.%i32) [template = constants.%C.3] -// CHECK:STDOUT: %.loc20_13.1: %C.3 = as_compatible %a.ref -// CHECK:STDOUT: %.loc20_13.2: %C.3 = converted %a.ref, %.loc20_13.1 +// CHECK:STDOUT: %C.ref: %C.type = name_ref C, file.%C.decl [template = constants.%C.1] +// CHECK:STDOUT: %.loc13_18: Core.IntLiteral = int_value 32 [template = constants.%.4] +// CHECK:STDOUT: %int.make_type_signed.loc13: init type = call constants.%Int(%.loc13_18) [template = constants.%i32] +// CHECK:STDOUT: %.loc13_17.1: type = value_of_initializer %int.make_type_signed.loc13 [template = constants.%i32] +// CHECK:STDOUT: %.loc13_17.2: type = converted %int.make_type_signed.loc13, %.loc13_17.1 [template = constants.%i32] +// CHECK:STDOUT: %C: type = class_type @C, @C(constants.%i32) [template = constants.%C.3] +// CHECK:STDOUT: %.loc13_13.1: %C.3 = as_compatible %a.ref +// CHECK:STDOUT: %.loc13_13.2: %C.3 = converted %a.ref, %.loc13_13.1 // CHECK:STDOUT: %x.ref: %.5 = name_ref x, @C.%.loc5_8.1 [template = @C.%.loc5_8.1] -// CHECK:STDOUT: %.loc20_23.1: ref %i32 = class_element_access %.loc20_13.2, element0 -// CHECK:STDOUT: %.loc20_23.2: %i32 = bind_value %.loc20_23.1 -// CHECK:STDOUT: %.loc20_25: %C.3 = converted %.loc20_23.2, [template = ] -// CHECK:STDOUT: return to %return +// CHECK:STDOUT: %.loc13_23.1: ref %i32 = class_element_access %.loc13_13.2, element0 +// CHECK:STDOUT: %.loc13_23.2: %i32 = bind_value %.loc13_23.1 +// CHECK:STDOUT: return %.loc13_23.2 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%T) { @@ -282,7 +283,7 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: imports { // CHECK:STDOUT: %import_ref.1: %C.type = import_ref Main//adapt_specific_type, inst+9, loaded [template = constants.%C.1] // CHECK:STDOUT: %import_ref.2: type = import_ref Main//adapt_specific_type, inst+26, loaded [template = constants.%Adapter] -// CHECK:STDOUT: %import_ref.3 = import_ref Main//adapt_specific_type, inst+69, unloaded +// CHECK:STDOUT: %import_ref.3 = import_ref Main//adapt_specific_type, inst+67, unloaded // CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { // CHECK:STDOUT: .Int = %import_ref.8 // CHECK:STDOUT: import Core//prelude @@ -433,20 +434,18 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: %Access.decl: %Access.type = fn_decl @Access [template = constants.%Access] { // CHECK:STDOUT: %a.patt: %Adapter = binding_pattern a // CHECK:STDOUT: %a.param_patt: %Adapter = value_param_pattern %a.patt, runtime_param0 -// CHECK:STDOUT: %return.patt: %C.3 = return_slot_pattern -// CHECK:STDOUT: %return.param_patt: %C.3 = out_param_pattern %return.patt, runtime_param1 +// CHECK:STDOUT: %return.patt: %i32 = return_slot_pattern +// CHECK:STDOUT: %return.param_patt: %i32 = out_param_pattern %return.patt, runtime_param1 // CHECK:STDOUT: } { // CHECK:STDOUT: %Adapter.ref: type = name_ref Adapter, file.%Adapter.decl [template = constants.%Adapter] -// CHECK:STDOUT: %C.ref: %C.type = name_ref C, file.%C.decl [template = constants.%C.1] -// CHECK:STDOUT: %.loc12_28: Core.IntLiteral = int_value 32 [template = constants.%.4] -// CHECK:STDOUT: %int.make_type_signed: init type = call constants.%Int(%.loc12_28) [template = constants.%i32] -// CHECK:STDOUT: %.loc12_27.1: type = value_of_initializer %int.make_type_signed [template = constants.%i32] -// CHECK:STDOUT: %.loc12_27.2: type = converted %int.make_type_signed, %.loc12_27.1 [template = constants.%i32] -// CHECK:STDOUT: %C: type = class_type @C, @C(constants.%i32) [template = constants.%C.3] +// CHECK:STDOUT: %.loc12_26.1: Core.IntLiteral = int_value 32 [template = constants.%.4] +// CHECK:STDOUT: %int.make_type_signed: init type = call constants.%Int(%.loc12_26.1) [template = constants.%i32] +// CHECK:STDOUT: %.loc12_26.2: type = value_of_initializer %int.make_type_signed [template = constants.%i32] +// CHECK:STDOUT: %.loc12_26.3: type = converted %int.make_type_signed, %.loc12_26.2 [template = constants.%i32] // CHECK:STDOUT: %a.param: %Adapter = value_param runtime_param0 // CHECK:STDOUT: %a: %Adapter = bind_name a, %a.param -// CHECK:STDOUT: %return.param: ref %C.3 = out_param runtime_param1 -// CHECK:STDOUT: %return: ref %C.3 = return_slot %return.param +// CHECK:STDOUT: %return.param: ref %i32 = out_param runtime_param1 +// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: @@ -486,14 +485,117 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: extend %C // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @Access(%a.param_patt: %Adapter) -> %return: %C.3 { +// CHECK:STDOUT: fn @Access(%a.param_patt: %Adapter) -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %a.ref: %Adapter = name_ref a, %a // CHECK:STDOUT: %x.ref: %.5 = name_ref x, @C.%.loc5_8.1 [template = @C.%.loc5_8.1] -// CHECK:STDOUT: %.loc27_11.1: %C.3 = converted %a.ref, [template = ] -// CHECK:STDOUT: %.loc27_11.2: %i32 = class_element_access , element0 [template = ] -// CHECK:STDOUT: %.loc27_13: %C.3 = converted %.loc27_11.2, [template = ] -// CHECK:STDOUT: return to %return +// CHECK:STDOUT: %.loc21_11.1: %C.3 = converted %a.ref, [template = ] +// CHECK:STDOUT: %.loc21_11.2: %i32 = class_element_access , element0 [template = ] +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C(constants.%T) { +// CHECK:STDOUT: %T.loc4_9.2 => constants.%T +// CHECK:STDOUT: %T.patt.loc4_9.2 => constants.%T +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C(%T.loc4_9.2) { +// CHECK:STDOUT: %T.loc4_9.2 => constants.%T +// CHECK:STDOUT: %T.patt.loc4_9.2 => constants.%T +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C(constants.%i32) { +// CHECK:STDOUT: %T.loc4_9.2 => constants.%i32 +// CHECK:STDOUT: %T.patt.loc4_9.2 => constants.%i32 +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C => constants.%C.3 +// CHECK:STDOUT: %.loc5_8.2 => constants.%.5 +// CHECK:STDOUT: %.loc6_1.2 => constants.%.6 +// CHECK:STDOUT: %.loc6_1.3 => constants.%.7 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- extend_adapt_specific_type_copy.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] +// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0 [symbolic] +// CHECK:STDOUT: %C.type: type = generic_class_type @C [template] +// CHECK:STDOUT: %C.1: %C.type = struct_value () [template] +// CHECK:STDOUT: %C.2: type = class_type @C, @C(%T) [symbolic] +// CHECK:STDOUT: %.1: type = unbound_element_type %C.2, %T [symbolic] +// CHECK:STDOUT: %.2: type = struct_type {.x: %T} [symbolic] +// CHECK:STDOUT: %.3: = complete_type_witness %.2 [symbolic] +// CHECK:STDOUT: %Adapter: type = class_type @Adapter [template] +// CHECK:STDOUT: %.4: Core.IntLiteral = int_value 32 [template] +// CHECK:STDOUT: %Int.type: type = fn_type @Int [template] +// CHECK:STDOUT: %Int: %Int.type = struct_value () [template] +// CHECK:STDOUT: %i32: type = int_type signed, %.4 [template] +// CHECK:STDOUT: %C.3: type = class_type @C, @C(%i32) [template] +// CHECK:STDOUT: %.5: type = unbound_element_type %C.3, %i32 [template] +// CHECK:STDOUT: %.6: type = struct_type {.x: %i32} [template] +// CHECK:STDOUT: %.7: = complete_type_witness %.6 [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { +// CHECK:STDOUT: .Int = %import_ref +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .Adapter = %Adapter.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %C.decl: %C.type = class_decl @C [template = constants.%C.1] { +// CHECK:STDOUT: %T.patt.loc4_9.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_9.2 (constants.%T.patt)] +// CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc4_9.1, runtime_param [symbolic = %T.patt.loc4_9.2 (constants.%T.patt)] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %T.param: type = value_param runtime_param +// CHECK:STDOUT: %T.loc4_9.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc4_9.2 (constants.%T)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %Adapter.decl: type = class_decl @Adapter [template = constants.%Adapter] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic class @C(%T.loc4_9.1: type) { +// CHECK:STDOUT: %T.loc4_9.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_9.2 (constants.%T)] +// CHECK:STDOUT: %T.patt.loc4_9.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_9.2 (constants.%T.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C: type = class_type @C, @C(%T.loc4_9.2) [symbolic = %C (constants.%C.2)] +// CHECK:STDOUT: %.loc5_8.2: type = unbound_element_type @C.%C (%C.2), @C.%T.loc4_9.2 (%T) [symbolic = %.loc5_8.2 (constants.%.1)] +// CHECK:STDOUT: %.loc6_1.2: type = struct_type {.x: @C.%T.loc4_9.2 (%T)} [symbolic = %.loc6_1.2 (constants.%.2)] +// CHECK:STDOUT: %.loc6_1.3: = complete_type_witness @C.%.loc6_1.2 (%.2) [symbolic = %.loc6_1.3 (constants.%.3)] +// CHECK:STDOUT: +// CHECK:STDOUT: class { +// CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc4_9.1 [symbolic = %T.loc4_9.2 (constants.%T)] +// CHECK:STDOUT: %.loc5_8.1: @C.%.loc5_8.2 (%.1) = field_decl x, element0 [template] +// CHECK:STDOUT: %.loc6_1.1: = complete_type_witness %.2 [symbolic = %.loc6_1.3 (constants.%.3)] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C.2 +// CHECK:STDOUT: .x = %.loc5_8.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Adapter { +// CHECK:STDOUT: %C.ref: %C.type = name_ref C, file.%C.decl [template = constants.%C.1] +// CHECK:STDOUT: %.loc9_18: Core.IntLiteral = int_value 32 [template = constants.%.4] +// CHECK:STDOUT: %int.make_type_signed: init type = call constants.%Int(%.loc9_18) [template = constants.%i32] +// CHECK:STDOUT: %.loc9_17.1: type = value_of_initializer %int.make_type_signed [template = constants.%i32] +// CHECK:STDOUT: %.loc9_17.2: type = converted %int.make_type_signed, %.loc9_17.1 [template = constants.%i32] +// CHECK:STDOUT: %C: type = class_type @C, @C(constants.%i32) [template = constants.%C.3] +// CHECK:STDOUT: adapt_decl %C [template] +// CHECK:STDOUT: %.loc10: = complete_type_witness %.6 [template = constants.%.7] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%Adapter +// CHECK:STDOUT: extend %C // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%T) { @@ -523,8 +625,6 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: %Adapter: type = class_type @Adapter [template] // CHECK:STDOUT: %.1: Core.IntLiteral = int_value 32 [template] // CHECK:STDOUT: %i32: type = int_type signed, %.1 [template] -// CHECK:STDOUT: %C.type: type = generic_class_type @C [template] -// CHECK:STDOUT: %C.1: %C.type = struct_value () [template] // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] // CHECK:STDOUT: %.2: type = struct_type {.x: %T} [symbolic] // CHECK:STDOUT: %.3: = complete_type_witness %.2 [symbolic] @@ -542,24 +642,24 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %import_ref.1: %C.type = import_ref Main//adapt_specific_type, inst+9, loaded [template = constants.%C.1] -// CHECK:STDOUT: %import_ref.2: type = import_ref Main//adapt_specific_type, inst+26, loaded [template = constants.%Adapter] -// CHECK:STDOUT: %import_ref.3 = import_ref Main//adapt_specific_type, inst+69, unloaded +// CHECK:STDOUT: %import_ref.1 = import_ref Main//extend_adapt_specific_type_copy, inst+9, unloaded +// CHECK:STDOUT: %import_ref.2: type = import_ref Main//extend_adapt_specific_type_copy, inst+26, loaded [template = constants.%Adapter] // CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { // CHECK:STDOUT: .Int = %import_ref.8 +// CHECK:STDOUT: .ImplicitAs = %import_ref.9 // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.4 = import_ref Main//adapt_specific_type, inst+15, unloaded -// CHECK:STDOUT: %import_ref.5: @C.%.1 (%.6) = import_ref Main//adapt_specific_type, inst+18, loaded [template = %.1] -// CHECK:STDOUT: %import_ref.7 = import_ref Main//adapt_specific_type, inst+27, unloaded +// CHECK:STDOUT: %import_ref.3 = import_ref Main//extend_adapt_specific_type_copy, inst+15, unloaded +// CHECK:STDOUT: %import_ref.4: @C.%.1 (%.6) = import_ref Main//extend_adapt_specific_type_copy, inst+18, loaded [template = %.1] +// CHECK:STDOUT: %import_ref.6 = import_ref Main//extend_adapt_specific_type_copy, inst+27, unloaded +// CHECK:STDOUT: %import_ref.7: type = import_ref Main//extend_adapt_specific_type_copy, inst+46, loaded [template = constants.%C.3] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: package: = namespace [template] { // CHECK:STDOUT: .C = imports.%import_ref.1 // CHECK:STDOUT: .Adapter = imports.%import_ref.2 -// CHECK:STDOUT: .Access = imports.%import_ref.3 // CHECK:STDOUT: .Core = imports.%Core // CHECK:STDOUT: .ImportedAccess = %ImportedAccess.decl // CHECK:STDOUT: } @@ -573,9 +673,9 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: } { // CHECK:STDOUT: %Adapter.ref: type = name_ref Adapter, imports.%import_ref.2 [template = constants.%Adapter] // CHECK:STDOUT: %.loc6_34.1: Core.IntLiteral = int_value 32 [template = constants.%.1] -// CHECK:STDOUT: %int.make_type_signed.loc6: init type = call constants.%Int(%.loc6_34.1) [template = constants.%i32] -// CHECK:STDOUT: %.loc6_34.2: type = value_of_initializer %int.make_type_signed.loc6 [template = constants.%i32] -// CHECK:STDOUT: %.loc6_34.3: type = converted %int.make_type_signed.loc6, %.loc6_34.2 [template = constants.%i32] +// CHECK:STDOUT: %int.make_type_signed: init type = call constants.%Int(%.loc6_34.1) [template = constants.%i32] +// CHECK:STDOUT: %.loc6_34.2: type = value_of_initializer %int.make_type_signed [template = constants.%i32] +// CHECK:STDOUT: %.loc6_34.3: type = converted %int.make_type_signed, %.loc6_34.2 [template = constants.%i32] // CHECK:STDOUT: %a.param: %Adapter = value_param runtime_param0 // CHECK:STDOUT: %a: %Adapter = bind_name a, %a.param // CHECK:STDOUT: %return.param: ref %i32 = out_param runtime_param1 @@ -585,7 +685,8 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: class @Adapter { // CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = imports.%import_ref.7 +// CHECK:STDOUT: .Self = imports.%import_ref.6 +// CHECK:STDOUT: extend imports.%import_ref.7 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: generic class @C(constants.%T: type) { @@ -600,26 +701,18 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: class { // CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = imports.%import_ref.4 -// CHECK:STDOUT: .x = imports.%import_ref.5 +// CHECK:STDOUT: .Self = imports.%import_ref.3 +// CHECK:STDOUT: .x = imports.%import_ref.4 // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @ImportedAccess(%a.param_patt: %Adapter) -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %a.ref: %Adapter = name_ref a, %a -// CHECK:STDOUT: %C.ref: %C.type = name_ref C, imports.%import_ref.1 [template = constants.%C.1] -// CHECK:STDOUT: %.loc8_18: Core.IntLiteral = int_value 32 [template = constants.%.1] -// CHECK:STDOUT: %int.make_type_signed.loc8: init type = call constants.%Int(%.loc8_18) [template = constants.%i32] -// CHECK:STDOUT: %.loc8_17.1: type = value_of_initializer %int.make_type_signed.loc8 [template = constants.%i32] -// CHECK:STDOUT: %.loc8_17.2: type = converted %int.make_type_signed.loc8, %.loc8_17.1 [template = constants.%i32] -// CHECK:STDOUT: %C: type = class_type @C, @C(constants.%i32) [template = constants.%C.3] -// CHECK:STDOUT: %.loc8_13.1: %C.3 = as_compatible %a.ref -// CHECK:STDOUT: %.loc8_13.2: %C.3 = converted %a.ref, %.loc8_13.1 -// CHECK:STDOUT: %x.ref: %.7 = name_ref x, imports.%import_ref.5 [template = imports.%.1] -// CHECK:STDOUT: %.loc8_23.1: ref %i32 = class_element_access %.loc8_13.2, element0 -// CHECK:STDOUT: %.loc8_23.2: %i32 = bind_value %.loc8_23.1 -// CHECK:STDOUT: return %.loc8_23.2 +// CHECK:STDOUT: %x.ref: %.7 = name_ref x, imports.%import_ref.4 [template = imports.%.1] +// CHECK:STDOUT: %.loc14_11.1: %C.3 = converted %a.ref, [template = ] +// CHECK:STDOUT: %.loc14_11.2: %i32 = class_element_access , element0 [template = ] +// CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%T) { From 8bdc0ea7972a420469ba63e7f29f9ce4a2ba0d92 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Wed, 27 Nov 2024 21:40:22 +0000 Subject: [PATCH 10/11] Rename file and add TODO comment describing the intent. --- .../check/testdata/class/generic/adapt.carbon | 79 ++++++++++--------- 1 file changed, 41 insertions(+), 38 deletions(-) diff --git a/toolchain/check/testdata/class/generic/adapt.carbon b/toolchain/check/testdata/class/generic/adapt.carbon index fbabe8be4109e..354f4a80ee174 100644 --- a/toolchain/check/testdata/class/generic/adapt.carbon +++ b/toolchain/check/testdata/class/generic/adapt.carbon @@ -58,7 +58,10 @@ fn Access(a: Adapter) -> i32 { return a.x; } -// --- extend_adapt_specific_type_copy.carbon +// --- extend_adapt_specific_type_library.carbon + +// TODO: Delete this file and change the next file to instead import the +// previous file once the previous file can be successfully type-checked. library "[[@TEST_NAME]]"; @@ -74,7 +77,7 @@ class Adapter { library "[[@TEST_NAME]]"; -import library "extend_adapt_specific_type_copy"; +import library "extend_adapt_specific_type_library"; fn ImportedAccess(a: Adapter) -> i32 { // TODO: This should presumably work, but the design doesn't say how yet. @@ -515,7 +518,7 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: %.loc6_1.3 => constants.%.7 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: --- extend_adapt_specific_type_copy.carbon +// CHECK:STDOUT: --- extend_adapt_specific_type_library.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] @@ -553,45 +556,45 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %C.decl: %C.type = class_decl @C [template = constants.%C.1] { -// CHECK:STDOUT: %T.patt.loc4_9.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_9.2 (constants.%T.patt)] -// CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc4_9.1, runtime_param [symbolic = %T.patt.loc4_9.2 (constants.%T.patt)] +// CHECK:STDOUT: %T.patt.loc7_9.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc7_9.2 (constants.%T.patt)] +// CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc7_9.1, runtime_param [symbolic = %T.patt.loc7_9.2 (constants.%T.patt)] // CHECK:STDOUT: } { // CHECK:STDOUT: %T.param: type = value_param runtime_param -// CHECK:STDOUT: %T.loc4_9.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc4_9.2 (constants.%T)] +// CHECK:STDOUT: %T.loc7_9.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc7_9.2 (constants.%T)] // CHECK:STDOUT: } // CHECK:STDOUT: %Adapter.decl: type = class_decl @Adapter [template = constants.%Adapter] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic class @C(%T.loc4_9.1: type) { -// CHECK:STDOUT: %T.loc4_9.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_9.2 (constants.%T)] -// CHECK:STDOUT: %T.patt.loc4_9.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_9.2 (constants.%T.patt)] +// CHECK:STDOUT: generic class @C(%T.loc7_9.1: type) { +// CHECK:STDOUT: %T.loc7_9.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc7_9.2 (constants.%T)] +// CHECK:STDOUT: %T.patt.loc7_9.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc7_9.2 (constants.%T.patt)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %C: type = class_type @C, @C(%T.loc4_9.2) [symbolic = %C (constants.%C.2)] -// CHECK:STDOUT: %.loc5_8.2: type = unbound_element_type @C.%C (%C.2), @C.%T.loc4_9.2 (%T) [symbolic = %.loc5_8.2 (constants.%.1)] -// CHECK:STDOUT: %.loc6_1.2: type = struct_type {.x: @C.%T.loc4_9.2 (%T)} [symbolic = %.loc6_1.2 (constants.%.2)] -// CHECK:STDOUT: %.loc6_1.3: = complete_type_witness @C.%.loc6_1.2 (%.2) [symbolic = %.loc6_1.3 (constants.%.3)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%T.loc7_9.2) [symbolic = %C (constants.%C.2)] +// CHECK:STDOUT: %.loc8_8.2: type = unbound_element_type @C.%C (%C.2), @C.%T.loc7_9.2 (%T) [symbolic = %.loc8_8.2 (constants.%.1)] +// CHECK:STDOUT: %.loc9_1.2: type = struct_type {.x: @C.%T.loc7_9.2 (%T)} [symbolic = %.loc9_1.2 (constants.%.2)] +// CHECK:STDOUT: %.loc9_1.3: = complete_type_witness @C.%.loc9_1.2 (%.2) [symbolic = %.loc9_1.3 (constants.%.3)] // CHECK:STDOUT: // CHECK:STDOUT: class { -// CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc4_9.1 [symbolic = %T.loc4_9.2 (constants.%T)] -// CHECK:STDOUT: %.loc5_8.1: @C.%.loc5_8.2 (%.1) = field_decl x, element0 [template] -// CHECK:STDOUT: %.loc6_1.1: = complete_type_witness %.2 [symbolic = %.loc6_1.3 (constants.%.3)] +// CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc7_9.1 [symbolic = %T.loc7_9.2 (constants.%T)] +// CHECK:STDOUT: %.loc8_8.1: @C.%.loc8_8.2 (%.1) = field_decl x, element0 [template] +// CHECK:STDOUT: %.loc9_1.1: = complete_type_witness %.2 [symbolic = %.loc9_1.3 (constants.%.3)] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%C.2 -// CHECK:STDOUT: .x = %.loc5_8.1 +// CHECK:STDOUT: .x = %.loc8_8.1 // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @Adapter { // CHECK:STDOUT: %C.ref: %C.type = name_ref C, file.%C.decl [template = constants.%C.1] -// CHECK:STDOUT: %.loc9_18: Core.IntLiteral = int_value 32 [template = constants.%.4] -// CHECK:STDOUT: %int.make_type_signed: init type = call constants.%Int(%.loc9_18) [template = constants.%i32] -// CHECK:STDOUT: %.loc9_17.1: type = value_of_initializer %int.make_type_signed [template = constants.%i32] -// CHECK:STDOUT: %.loc9_17.2: type = converted %int.make_type_signed, %.loc9_17.1 [template = constants.%i32] +// CHECK:STDOUT: %.loc12_18: Core.IntLiteral = int_value 32 [template = constants.%.4] +// CHECK:STDOUT: %int.make_type_signed: init type = call constants.%Int(%.loc12_18) [template = constants.%i32] +// CHECK:STDOUT: %.loc12_17.1: type = value_of_initializer %int.make_type_signed [template = constants.%i32] +// CHECK:STDOUT: %.loc12_17.2: type = converted %int.make_type_signed, %.loc12_17.1 [template = constants.%i32] // CHECK:STDOUT: %C: type = class_type @C, @C(constants.%i32) [template = constants.%C.3] // CHECK:STDOUT: adapt_decl %C [template] -// CHECK:STDOUT: %.loc10: = complete_type_witness %.6 [template = constants.%.7] +// CHECK:STDOUT: %.loc13: = complete_type_witness %.6 [template = constants.%.7] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%Adapter @@ -599,24 +602,24 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%T) { -// CHECK:STDOUT: %T.loc4_9.2 => constants.%T -// CHECK:STDOUT: %T.patt.loc4_9.2 => constants.%T +// CHECK:STDOUT: %T.loc7_9.2 => constants.%T +// CHECK:STDOUT: %T.patt.loc7_9.2 => constants.%T // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @C(%T.loc4_9.2) { -// CHECK:STDOUT: %T.loc4_9.2 => constants.%T -// CHECK:STDOUT: %T.patt.loc4_9.2 => constants.%T +// CHECK:STDOUT: specific @C(%T.loc7_9.2) { +// CHECK:STDOUT: %T.loc7_9.2 => constants.%T +// CHECK:STDOUT: %T.patt.loc7_9.2 => constants.%T // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%i32) { -// CHECK:STDOUT: %T.loc4_9.2 => constants.%i32 -// CHECK:STDOUT: %T.patt.loc4_9.2 => constants.%i32 +// CHECK:STDOUT: %T.loc7_9.2 => constants.%i32 +// CHECK:STDOUT: %T.patt.loc7_9.2 => constants.%i32 // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: %C => constants.%C.3 -// CHECK:STDOUT: %.loc5_8.2 => constants.%.5 -// CHECK:STDOUT: %.loc6_1.2 => constants.%.6 -// CHECK:STDOUT: %.loc6_1.3 => constants.%.7 +// CHECK:STDOUT: %.loc8_8.2 => constants.%.5 +// CHECK:STDOUT: %.loc9_1.2 => constants.%.6 +// CHECK:STDOUT: %.loc9_1.3 => constants.%.7 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: --- fail_todo_import_extend_adapt_specific_type.carbon @@ -642,18 +645,18 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %import_ref.1 = import_ref Main//extend_adapt_specific_type_copy, inst+9, unloaded -// CHECK:STDOUT: %import_ref.2: type = import_ref Main//extend_adapt_specific_type_copy, inst+26, loaded [template = constants.%Adapter] +// CHECK:STDOUT: %import_ref.1 = import_ref Main//extend_adapt_specific_type_library, inst+9, unloaded +// CHECK:STDOUT: %import_ref.2: type = import_ref Main//extend_adapt_specific_type_library, inst+26, loaded [template = constants.%Adapter] // CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { // CHECK:STDOUT: .Int = %import_ref.8 // CHECK:STDOUT: .ImplicitAs = %import_ref.9 // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.3 = import_ref Main//extend_adapt_specific_type_copy, inst+15, unloaded -// CHECK:STDOUT: %import_ref.4: @C.%.1 (%.6) = import_ref Main//extend_adapt_specific_type_copy, inst+18, loaded [template = %.1] -// CHECK:STDOUT: %import_ref.6 = import_ref Main//extend_adapt_specific_type_copy, inst+27, unloaded -// CHECK:STDOUT: %import_ref.7: type = import_ref Main//extend_adapt_specific_type_copy, inst+44, loaded [template = constants.%C.3] +// CHECK:STDOUT: %import_ref.3 = import_ref Main//extend_adapt_specific_type_library, inst+15, unloaded +// CHECK:STDOUT: %import_ref.4: @C.%.1 (%.6) = import_ref Main//extend_adapt_specific_type_library, inst+18, loaded [template = %.1] +// CHECK:STDOUT: %import_ref.6 = import_ref Main//extend_adapt_specific_type_library, inst+27, unloaded +// CHECK:STDOUT: %import_ref.7: type = import_ref Main//extend_adapt_specific_type_library, inst+44, loaded [template = constants.%C.3] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { From a838158c70235800bb047460386aa739855251f2 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Wed, 27 Nov 2024 22:14:15 +0000 Subject: [PATCH 11/11] Autoupdate. --- toolchain/check/testdata/class/virtual_modifiers.carbon | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/toolchain/check/testdata/class/virtual_modifiers.carbon b/toolchain/check/testdata/class/virtual_modifiers.carbon index 64d54021ec6ab..5f3a8623be109 100644 --- a/toolchain/check/testdata/class/virtual_modifiers.carbon +++ b/toolchain/check/testdata/class/virtual_modifiers.carbon @@ -336,7 +336,7 @@ class Derived { // CHECK:STDOUT: // CHECK:STDOUT: class @A2 { // CHECK:STDOUT: %A1.ref: type = name_ref A1, file.%A1.decl [template = constants.%A1] -// CHECK:STDOUT: %.loc9: %.5 = base_decl %A1, element0 [template] +// CHECK:STDOUT: %.loc9: %.5 = base_decl %A1.ref, element0 [template] // CHECK:STDOUT: %F.decl: %F.type.2 = fn_decl @F.2 [template = constants.%F.2] {} {} // CHECK:STDOUT: %.loc11: = complete_type_witness %.6 [template = constants.%.7] // CHECK:STDOUT: @@ -405,7 +405,7 @@ class Derived { // CHECK:STDOUT: // CHECK:STDOUT: class @B2 { // CHECK:STDOUT: %B1.ref: type = name_ref B1, file.%B1.decl [template = constants.%B1] -// CHECK:STDOUT: %.loc9: %.5 = base_decl %B1, element0 [template] +// CHECK:STDOUT: %.loc9: %.5 = base_decl %B1.ref, element0 [template] // CHECK:STDOUT: %F.decl: %F.type.2 = fn_decl @F.2 [template = constants.%F.2] {} {} // CHECK:STDOUT: %.loc11: = complete_type_witness %.6 [template = constants.%.7] // CHECK:STDOUT: @@ -418,7 +418,7 @@ class Derived { // CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %B2.ref: type = name_ref B2, file.%B2.decl [template = constants.%B2] -// CHECK:STDOUT: %.loc14: %.10 = base_decl %B2, element0 [template] +// CHECK:STDOUT: %.loc14: %.10 = base_decl %B2.ref, element0 [template] // CHECK:STDOUT: %F.decl: %F.type.3 = fn_decl @F.3 [template = constants.%F.3] {} {} // CHECK:STDOUT: %.loc16: = complete_type_witness %.11 [template = constants.%.12] // CHECK:STDOUT: