Track the type as written in BaseDecl and AdaptDecl. (#4564)

Represent the type as an `InstId` rather than as a `TypeId` to preserve
how it was written and better support tracking its value in a generic.
Add accessors to `Class` to get the base and adapted type to reduce code
duplication, and add `TypeStore::GetObjectRepr` to make it easier to map
from a type to its possibly-adapted object representation type. In
passing, also move `GetIntTypeInfo` and `GetUnqualifiedType` into
`TypeStore`.

This fixes specifics of generic adapters to properly look at the
specific adapted type, and also fixes importing of adapters.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
This commit is contained in:
Richard Smith
2024-11-27 22:26:30 +00:00
committed by GitHub
co-authored by Jon Ross-Perkins
parent e0db74a2a1
commit d6ec885eb3
51 changed files with 1530 additions and 415 deletions
+20 -22
View File
@@ -390,18 +390,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<SemIR::BaseDecl>(
class_info.base_id)) {
parent_type_id = base_decl->base_type_id;
} else if (auto adapt_decl =
context.insts().TryGetAsIfValid<SemIR::AdaptDecl>(
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");
}
@@ -957,7 +958,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): {
@@ -1127,12 +1134,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<SemIR::AdaptDecl>(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.
@@ -1400,13 +1405,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<SemIR::ConstType>(type_id)) {
return const_type->inner_id;
}
return type_id;
}
auto Context::PrintForStackDump(llvm::raw_ostream& output) const -> void {
output << "Check::Context\n";
-3
View File
@@ -431,9 +431,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); }
+10 -10
View File
@@ -607,15 +607,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<SemIR::BaseDecl>(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;
}
@@ -712,12 +709,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<SemIR::ClassType>(type_id)) {
while (auto class_type =
context.types().TryGetAs<SemIR::ClassType>(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.
+7 -5
View File
@@ -676,7 +676,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();
@@ -718,7 +718,8 @@ static auto PerformBuiltinUnaryIntOp(Context& context, SemIRLoc loc,
SemIR::InstId arg_id)
-> SemIR::ConstantId {
auto op = context.insts().GetAs<SemIR::IntValue>(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);
@@ -771,7 +772,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;
@@ -916,7 +917,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);
@@ -1497,6 +1499,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:
@@ -1699,7 +1702,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:
+26 -34
View File
@@ -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,23 @@ 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);
"adapted type {0} is an abstract type", 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<SemIR::AdaptDecl>(
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 +435,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.
@@ -531,7 +535,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<SemIR::BaseDecl>(
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::Invalid});
if (base_info.type_id != SemIR::TypeId::Error) {
@@ -607,27 +611,17 @@ 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<SemIR::AdaptDecl>(class_info.adapt_id)
.adapted_type_id;
if (auto adapted_class =
context.types().TryGetAs<SemIR::ClassType>(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<SemIR::CompleteTypeWitness>(
node_id,
{.type_id = context.GetBuiltinType(SemIR::BuiltinInstKind::WitnessType),
.object_repr_id = adapted_type_id});
.object_repr_id = object_repr_id});
}
static auto AddStructTypeFields(
Context& context,
llvm::SmallVector<SemIR::StructTypeField>& struct_type_fields)
@@ -664,11 +658,12 @@ static auto CheckCompleteClassType(Context& context, Parse::NodeId node_id,
}
bool defining_vptr = class_info.is_dynamic;
if (class_info.base_id.is_valid()) {
auto base_info = context.insts().GetAs<SemIR::BaseDecl>(class_info.base_id);
auto base_type_id =
class_info.GetBaseType(context.sem_ir(), SemIR::SpecificId::Invalid);
if (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_info.base_type_id);
if (auto* base_class_info = TryGetAsClass(context, base_type_id);
base_class_info && base_class_info->is_dynamic) {
defining_vptr = false;
}
@@ -684,16 +679,13 @@ static auto CheckCompleteClassType(Context& context, Parse::NodeId node_id,
.type_id = context.GetPointerType(
context.GetBuiltinType(SemIR::BuiltinInstKind::VtableType))});
}
if (class_info.base_id.is_valid()) {
if (base_type_id.is_valid()) {
auto base_decl = context.insts().GetAs<SemIR::BaseDecl>(class_info.base_id);
base_decl.index =
SemIR::ElementIndex{static_cast<int>(struct_type_fields.size())};
context.ReplaceInstPreservingConstantValue(class_info.base_id, base_decl);
struct_type_fields.push_back(
{.name_id = SemIR::NameId::Base,
.type_id = context.insts()
.GetAs<SemIR::BaseDecl>(class_info.base_id)
.base_type_id});
{.name_id = SemIR::NameId::Base, .type_id = base_type_id});
}
return context.AddInst<SemIR::CompleteTypeWitness>(
+42 -7
View File
@@ -1252,6 +1252,28 @@ static auto ResolveAs(ImportContext& context, InstT inst) -> ResolveResult {
return ResolveAsUntyped(context, inst);
}
static auto TryResolveTypedInst(ImportRefResolver& resolver,
SemIR::AdaptDecl inst,
SemIR::InstId import_inst_id) -> ResolveResult {
auto adapted_type_const_id = GetLocalConstantId(
resolver,
resolver.import_constant_values().Get(inst.adapted_type_inst_id));
if (resolver.HasNewWork()) {
return ResolveResult::Retry();
}
auto adapted_type_inst_id =
AddLoadedImportRef(resolver, SemIR::TypeId::TypeType,
inst.adapted_type_inst_id, adapted_type_const_id);
// Create a corresponding instruction to represent the declaration.
auto inst_id = resolver.local_context().AddInstInNoBlock(
resolver.local_context().MakeImportedLocAndInst<SemIR::AdaptDecl>(
AddImportIRInst(resolver, import_inst_id),
{.adapted_type_inst_id = adapted_type_inst_id}));
return ResolveResult::Done(resolver.local_constant_values().Get(inst_id));
}
static auto TryResolveTypedInst(ImportRefResolver& resolver,
SemIR::AssociatedEntity inst) -> ResolveResult {
auto type_const_id = GetLocalConstantId(resolver, inst.type_id);
@@ -1293,20 +1315,23 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
SemIR::BaseDecl inst,
SemIR::InstId import_inst_id) -> ResolveResult {
auto type_const_id = GetLocalConstantId(resolver, inst.type_id);
auto base_type_const_id = GetLocalConstantId(resolver, inst.base_type_id);
auto base_type_const_id = GetLocalConstantId(
resolver, resolver.import_constant_values().Get(inst.base_type_inst_id));
if (resolver.HasNewWork()) {
return ResolveResult::Retry();
}
// Import the instruction in order to update contained base_type_id and
// track the import location.
auto base_type_inst_id =
AddLoadedImportRef(resolver, SemIR::TypeId::TypeType,
inst.base_type_inst_id, base_type_const_id);
// Create a corresponding instruction to represent the declaration.
auto inst_id = resolver.local_context().AddInstInNoBlock(
resolver.local_context().MakeImportedLocAndInst<SemIR::BaseDecl>(
AddImportIRInst(resolver, import_inst_id),
{.type_id =
resolver.local_context().GetTypeIdForTypeConstant(type_const_id),
.base_type_id = resolver.local_context().GetTypeIdForTypeConstant(
base_type_const_id),
.base_type_inst_id = base_type_inst_id,
.index = inst.index}));
return ResolveResult::Done(resolver.local_constant_values().Get(inst_id));
}
@@ -1397,7 +1422,8 @@ static auto AddClassDefinition(ImportContext& context,
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;
@@ -1417,6 +1443,9 @@ static auto AddClassDefinition(ImportContext& context,
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;
}
}
static auto TryResolveTypedInst(ImportRefResolver& resolver,
@@ -1480,6 +1509,9 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
auto base_id = import_class.base_id.is_valid()
? GetLocalConstantInstId(resolver, import_class.base_id)
: SemIR::InstId::Invalid;
auto adapt_id = import_class.adapt_id.is_valid()
? GetLocalConstantInstId(resolver, import_class.adapt_id)
: SemIR::InstId::Invalid;
if (resolver.HasNewWork()) {
return ResolveResult::Retry(class_const_id);
@@ -1498,7 +1530,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
if (import_class.is_defined()) {
AddClassDefinition(resolver, import_class, new_class,
complete_type_witness_id, base_id);
complete_type_witness_id, base_id, adapt_id);
}
return ResolveResult::Done(class_const_id);
@@ -2328,6 +2360,9 @@ static auto TryResolveInstCanonical(ImportRefResolver& resolver,
auto untyped_inst = resolver.import_insts().Get(inst_id);
CARBON_KIND_SWITCH(untyped_inst) {
case CARBON_KIND(SemIR::AdaptDecl inst): {
return TryResolveTypedInst(resolver, inst, inst_id);
}
case CARBON_KIND(SemIR::AssociatedEntity inst): {
return TryResolveTypedInst(resolver, inst);
}
+11 -7
View File
@@ -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<SemIR::BaseDecl>(
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<SemIR::AdaptDecl>(
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;
}
}
+2 -2
View File
@@ -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<SemIR::PointerType>(type_id)) {
+63 -63
View File
@@ -133,8 +133,7 @@ var b: B = {.x = 1} as B;
// CHECK:STDOUT: %.38: %i32 = int_value 2 [template]
// CHECK:STDOUT: %struct: %A = struct_value (%.35, %.38) [template]
// CHECK:STDOUT: %B: type = class_type @B [template]
// CHECK:STDOUT: %.39: <witness> = complete_type_witness %A [template]
// CHECK:STDOUT: %.40: type = ptr_type %B [template]
// CHECK:STDOUT: %.39: 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.%.40]
// CHECK:STDOUT: %.loc22: type = ptr_type %B [template = constants.%.39]
// 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: <witness> = complete_type_witness %A [template = constants.%.39]
// CHECK:STDOUT: adapt_decl %A.ref [template]
// CHECK:STDOUT: %.loc15: <witness> = 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: %.40 = addr_of %.loc22_25.2
// CHECK:STDOUT: %b_ptr: %.40 = bind_name b_ptr, %.loc22_17
// CHECK:STDOUT: %.loc22_17: %.39 = addr_of %.loc22_25.2
// CHECK:STDOUT: %b_ptr: %.39 = 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 [template]
// CHECK:STDOUT: %.loc6: <witness> = 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 [template]
// CHECK:STDOUT: %.loc4_21: <witness> = 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 [template]
// CHECK:STDOUT: %.loc5: <witness> = 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 [template]
// CHECK:STDOUT: %.loc6: <witness> = 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 [template]
// CHECK:STDOUT: %.loc7: <witness> = 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: <witness> = complete_type_witness %.3 [template]
// CHECK:STDOUT: %B: type = class_type @B [template]
// CHECK:STDOUT: %.6: <witness> = 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: %.33: <witness> = interface_witness (%Convert.14) [template]
// CHECK:STDOUT: %.34: <bound method> = bound_method %.7, %Convert.14 [template]
// CHECK:STDOUT: %.35: <specific function> = specific_function %.34, @Convert.2(%.1) [template]
// CHECK:STDOUT: %.36: %i32 = int_value 1 [template]
// CHECK:STDOUT: %.37: <bound method> = bound_method %.8, %Convert.14 [template]
// CHECK:STDOUT: %.38: <specific function> = specific_function %.37, @Convert.2(%.1) [template]
// CHECK:STDOUT: %.39: %i32 = int_value 2 [template]
// CHECK:STDOUT: %struct: %A = struct_value (%.36, %.39) [template]
// CHECK:STDOUT: %.32: <witness> = interface_witness (%Convert.14) [template]
// CHECK:STDOUT: %.33: <bound method> = bound_method %.6, %Convert.14 [template]
// CHECK:STDOUT: %.34: <specific function> = specific_function %.33, @Convert.2(%.1) [template]
// CHECK:STDOUT: %.35: %i32 = int_value 1 [template]
// CHECK:STDOUT: %.36: <bound method> = bound_method %.7, %Convert.14 [template]
// CHECK:STDOUT: %.37: <specific function> = specific_function %.36, @Convert.2(%.1) [template]
// CHECK:STDOUT: %.38: %i32 = int_value 2 [template]
// CHECK:STDOUT: %struct: %A = struct_value (%.35, %.38) [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: <witness> = complete_type_witness %A [template = constants.%.6]
// CHECK:STDOUT: adapt_decl %A.ref [template]
// CHECK:STDOUT: %.loc11: <witness> = 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.%.33, element0 [template = constants.%Convert.14]
// CHECK:STDOUT: %.loc13_34.3: <bound method> = bound_method %.loc13_25, %.loc13_34.2 [template = constants.%.34]
// CHECK:STDOUT: %.loc13_34.4: <specific function> = specific_function %.loc13_34.3, @Convert.2(constants.%.1) [template = constants.%.35]
// CHECK:STDOUT: %int.convert_checked.loc13_34.1: init %i32 = call %.loc13_34.4(%.loc13_25) [template = constants.%.36]
// CHECK:STDOUT: %.loc13_34.5: init %i32 = converted %.loc13_25, %int.convert_checked.loc13_34.1 [template = constants.%.36]
// CHECK:STDOUT: %.loc13_34.2: %Convert.type.2 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.14]
// CHECK:STDOUT: %.loc13_34.3: <bound method> = bound_method %.loc13_25, %.loc13_34.2 [template = constants.%.33]
// CHECK:STDOUT: %.loc13_34.4: <specific function> = specific_function %.loc13_34.3, @Convert.2(constants.%.1) [template = constants.%.34]
// CHECK:STDOUT: %int.convert_checked.loc13_34.1: init %i32 = call %.loc13_34.4(%.loc13_25) [template = constants.%.35]
// CHECK:STDOUT: %.loc13_34.5: init %i32 = converted %.loc13_25, %int.convert_checked.loc13_34.1 [template = constants.%.35]
// 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.%.36]
// CHECK:STDOUT: %.loc13_34.9: %Convert.type.2 = interface_witness_access constants.%.33, element0 [template = constants.%Convert.14]
// CHECK:STDOUT: %.loc13_34.10: <bound method> = bound_method %.loc13_33, %.loc13_34.9 [template = constants.%.37]
// CHECK:STDOUT: %.loc13_34.11: <specific function> = specific_function %.loc13_34.10, @Convert.2(constants.%.1) [template = constants.%.38]
// CHECK:STDOUT: %int.convert_checked.loc13_34.2: init %i32 = call %.loc13_34.11(%.loc13_33) [template = constants.%.39]
// CHECK:STDOUT: %.loc13_34.12: init %i32 = converted %.loc13_33, %int.convert_checked.loc13_34.2 [template = constants.%.39]
// CHECK:STDOUT: %.loc13_34.8: init %i32 = initialize_from %.loc13_34.5 to %.loc13_34.7 [template = constants.%.35]
// CHECK:STDOUT: %.loc13_34.9: %Convert.type.2 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.14]
// CHECK:STDOUT: %.loc13_34.10: <bound method> = bound_method %.loc13_33, %.loc13_34.9 [template = constants.%.36]
// CHECK:STDOUT: %.loc13_34.11: <specific function> = specific_function %.loc13_34.10, @Convert.2(constants.%.1) [template = constants.%.37]
// CHECK:STDOUT: %int.convert_checked.loc13_34.2: init %i32 = call %.loc13_34.11(%.loc13_33) [template = constants.%.38]
// CHECK:STDOUT: %.loc13_34.12: init %i32 = converted %.loc13_33, %int.convert_checked.loc13_34.2 [template = constants.%.38]
// 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.%.39]
// CHECK:STDOUT: %.loc13_34.14: init %i32 = initialize_from %.loc13_34.12 to %.loc13_34.13 [template = constants.%.38]
// 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.%.33, element0 [template = constants.%Convert.14]
// CHECK:STDOUT: %.loc24_33.3: <bound method> = bound_method %.loc24_24, %.loc24_33.2 [template = constants.%.34]
// CHECK:STDOUT: %.loc24_33.4: <specific function> = specific_function %.loc24_33.3, @Convert.2(constants.%.1) [template = constants.%.35]
// CHECK:STDOUT: %int.convert_checked.loc24_33.1: init %i32 = call %.loc24_33.4(%.loc24_24) [template = constants.%.36]
// CHECK:STDOUT: %.loc24_33.5: init %i32 = converted %.loc24_24, %int.convert_checked.loc24_33.1 [template = constants.%.36]
// CHECK:STDOUT: %.loc24_33.2: %Convert.type.2 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.14]
// CHECK:STDOUT: %.loc24_33.3: <bound method> = bound_method %.loc24_24, %.loc24_33.2 [template = constants.%.33]
// CHECK:STDOUT: %.loc24_33.4: <specific function> = specific_function %.loc24_33.3, @Convert.2(constants.%.1) [template = constants.%.34]
// CHECK:STDOUT: %int.convert_checked.loc24_33.1: init %i32 = call %.loc24_33.4(%.loc24_24) [template = constants.%.35]
// CHECK:STDOUT: %.loc24_33.5: init %i32 = converted %.loc24_24, %int.convert_checked.loc24_33.1 [template = constants.%.35]
// 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.%.36]
// CHECK:STDOUT: %.loc24_33.9: %Convert.type.2 = interface_witness_access constants.%.33, element0 [template = constants.%Convert.14]
// CHECK:STDOUT: %.loc24_33.10: <bound method> = bound_method %.loc24_32, %.loc24_33.9 [template = constants.%.37]
// CHECK:STDOUT: %.loc24_33.11: <specific function> = specific_function %.loc24_33.10, @Convert.2(constants.%.1) [template = constants.%.38]
// CHECK:STDOUT: %int.convert_checked.loc24_33.2: init %i32 = call %.loc24_33.11(%.loc24_32) [template = constants.%.39]
// CHECK:STDOUT: %.loc24_33.12: init %i32 = converted %.loc24_32, %int.convert_checked.loc24_33.2 [template = constants.%.39]
// CHECK:STDOUT: %.loc24_33.8: init %i32 = initialize_from %.loc24_33.5 to %.loc24_33.7 [template = constants.%.35]
// CHECK:STDOUT: %.loc24_33.9: %Convert.type.2 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.14]
// CHECK:STDOUT: %.loc24_33.10: <bound method> = bound_method %.loc24_32, %.loc24_33.9 [template = constants.%.36]
// CHECK:STDOUT: %.loc24_33.11: <specific function> = specific_function %.loc24_33.10, @Convert.2(constants.%.1) [template = constants.%.37]
// CHECK:STDOUT: %int.convert_checked.loc24_33.2: init %i32 = call %.loc24_33.11(%.loc24_32) [template = constants.%.38]
// CHECK:STDOUT: %.loc24_33.12: init %i32 = converted %.loc24_32, %int.convert_checked.loc24_33.2 [template = constants.%.38]
// 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.%.39]
// CHECK:STDOUT: %.loc24_33.14: init %i32 = initialize_from %.loc24_33.12 to %.loc24_33.13 [template = constants.%.38]
// 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: <witness> = complete_type_witness %.3 [template]
// CHECK:STDOUT: %B: type = class_type @B [template]
// CHECK:STDOUT: %.6: <witness> = 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: <witness> = complete_type_witness %A [template = constants.%.6]
// CHECK:STDOUT: adapt_decl %A.ref [template]
// CHECK:STDOUT: %.loc10: <witness> = 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, <error> [template = <error>]
// CHECK:STDOUT: assign file.%b.var, <error>
+5 -7
View File
@@ -57,7 +57,6 @@ fn F(a: AdaptNotExtend) {
// CHECK:STDOUT: %.3: type = struct_type {.a: %i32, .b: %i32} [template]
// CHECK:STDOUT: %.4: <witness> = complete_type_witness %.3 [template]
// CHECK:STDOUT: %SomeClassAdapter: type = class_type @SomeClassAdapter [template]
// CHECK:STDOUT: %.6: <witness> = 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: <witness> = complete_type_witness %SomeClass [template = constants.%.6]
// CHECK:STDOUT: adapt_decl %SomeClass.ref [template]
// CHECK:STDOUT: %.loc11: <witness> = 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 [template]
// CHECK:STDOUT: %.loc15: <witness> = 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: <witness> = complete_type_witness %.1 [template]
// CHECK:STDOUT: %AdaptNotExtend: type = class_type @AdaptNotExtend [template]
// CHECK:STDOUT: %.4: <witness> = 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: <witness> = complete_type_witness %Adapted [template = constants.%.4]
// CHECK:STDOUT: adapt_decl %Adapted.ref [template]
// CHECK:STDOUT: %.loc10: <witness> = complete_type_witness %.1 [template = constants.%.2]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%AdaptNotExtend
+1 -1
View File
@@ -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]
+1 -1
View File
@@ -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]
@@ -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: <witness> = complete_type_witness %.5 [template = constants.%.6]
+1 -1
View File
@@ -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: %.35 = base_decl %Base, element0 [template]
// CHECK:STDOUT: %.loc22: %.35 = base_decl %Base.ref, element0 [template]
// CHECK:STDOUT: %.loc23: <witness> = complete_type_witness %.36 [template = constants.%.37]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
@@ -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
+3 -3
View File
@@ -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: <witness> = complete_type_witness %.13 [template = constants.%.14]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
+1 -1
View File
@@ -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]
+2 -2
View File
@@ -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]
+9 -12
View File
@@ -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: <witness> = complete_type_witness %.3 [template]
// CHECK:STDOUT: %.6: <witness> = 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: <witness> = complete_type_witness %SomeClass [template = constants.%.6]
// CHECK:STDOUT: adapt_decl %SomeClass.ref [template]
// CHECK:STDOUT: %.loc17: <witness> = 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: <witness> = complete_type_witness %.1 [template]
// CHECK:STDOUT: %SomeClassAdapter: type = class_type @SomeClassAdapter [template]
// CHECK:STDOUT: %.4: <witness> = 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: <witness> = complete_type_witness %SomeClass [template = constants.%.4]
// CHECK:STDOUT: adapt_decl %SomeClass.ref [template]
// CHECK:STDOUT: %.loc10: <witness> = 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: <witness> = complete_type_witness %.3 [template]
// CHECK:STDOUT: %SomeClassAdapter: type = class_type @SomeClassAdapter [template]
// CHECK:STDOUT: %.6: <witness> = 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: <witness> = complete_type_witness %SomeClass [template = constants.%.6]
// CHECK:STDOUT: adapt_decl %SomeClass.ref [template]
// CHECK:STDOUT: %.loc11: <witness> = 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 [template]
// CHECK:STDOUT: %.loc6: <witness> = 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 [template]
// CHECK:STDOUT: %.loc6: <witness> = 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 [template]
// CHECK:STDOUT: %.loc8: <witness> = complete_type_witness %i32 [template = constants.%.2]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
+4 -4
View File
@@ -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 <error>
// CHECK:STDOUT: adapt_decl <error> [template]
// CHECK:STDOUT: %.loc17: <witness> = complete_type_witness <error> [template = <error>]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
@@ -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]
+4 -4
View File
@@ -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, <error> [template = <error>]
// CHECK:STDOUT: adapt_decl <error>
// CHECK:STDOUT: adapt_decl <error> [template]
// CHECK:STDOUT: %.loc13: <witness> = complete_type_witness <error> [template = <error>]
// 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, <error> [template = <error>]
// CHECK:STDOUT: adapt_decl <error>
// CHECK:STDOUT: adapt_decl <error> [template]
// CHECK:STDOUT: %.loc13: <witness> = complete_type_witness <error> [template = <error>]
// 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 %empty_tuple.type
// CHECK:STDOUT: adapt_decl %.loc5_11 [template]
// CHECK:STDOUT: %.loc13: %.1 = struct_literal ()
// CHECK:STDOUT: %.loc14: <witness> = 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 [template]
// CHECK:STDOUT: %.loc25: %empty_tuple.type = tuple_literal ()
// CHECK:STDOUT: %.loc26: <witness> = complete_type_witness %empty_tuple.type [template = constants.%.2]
// CHECK:STDOUT:
+1 -1
View File
@@ -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 <error>
// CHECK:STDOUT: adapt_decl <error> [template]
// CHECK:STDOUT: %.loc14: <witness> = complete_type_witness <error> [template = <error>]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
+10 -11
View File
@@ -62,7 +62,6 @@ class C5 {
// CHECK:STDOUT: %.1: type = struct_type {} [template]
// CHECK:STDOUT: %.2: <witness> = complete_type_witness %.1 [template]
// CHECK:STDOUT: %C1: type = class_type @C1 [template]
// CHECK:STDOUT: %.4: <witness> = 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: <witness> = complete_type_witness %B [template = constants.%.4]
// CHECK:STDOUT: adapt_decl %B.ref [template]
// CHECK:STDOUT: %.loc19: <witness> = 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: <witness> = complete_type_witness %B [template = constants.%.4]
// CHECK:STDOUT: adapt_decl %B.ref [template]
// CHECK:STDOUT: %.loc27: <witness> = 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: <witness> = complete_type_witness %B [template = constants.%.4]
// CHECK:STDOUT: adapt_decl %B.ref [template]
// CHECK:STDOUT: %.loc35: <witness> = 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: <witness> = complete_type_witness %B [template = constants.%.4]
// CHECK:STDOUT: adapt_decl %B.ref [template]
// CHECK:STDOUT: %.loc46: <witness> = 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: <witness> = complete_type_witness %B [template = constants.%.4]
// CHECK:STDOUT: adapt_decl %B.ref [template]
// CHECK:STDOUT: %.loc56: <witness> = complete_type_witness %.1 [template = constants.%.2]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%C5
+1 -1
View File
@@ -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 [template]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%AdaptWithVirtual
@@ -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 [template]
// CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base]
// CHECK:STDOUT: %.loc15: %.5 = base_decl %Base, element<invalid> [template]
// CHECK:STDOUT: %.loc15: %.5 = base_decl %Base.ref, element<invalid> [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 [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 %i32
// 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]
@@ -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, element<invalid> [template]
// CHECK:STDOUT: %.loc7: %.4 = base_decl %Base.ref, element<invalid> [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, element<invalid> [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 [template]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%AdaptWithBaseAndFields
+1 -1
View File
@@ -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: <witness> = complete_type_witness %.7 [template = constants.%.8]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
@@ -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: <witness> = complete_type_witness %.5 [template = constants.%.6]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
+4 -4
View File
@@ -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: <witness> = 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: <witness> = 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: <witness> = 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: <witness> = complete_type_witness %.5 [template = constants.%.6]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
+1 -1
View File
@@ -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: <witness> = complete_type_witness %.5 [template = constants.%.6]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
+2 -2
View File
@@ -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: <witness> = 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: <witness> = complete_type_witness %.5 [template = constants.%.6]
// CHECK:STDOUT:
+1 -1
View File
@@ -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: <witness> = complete_type_witness %.5 [template = constants.%.6]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
+1 -1
View File
@@ -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]
+2 -2
View File
@@ -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: <witness> = 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: <error> = name_ref C, <error> [template = <error>]
// CHECK:STDOUT: %.loc31: <error> = field_decl c, element1 [template]
// CHECK:STDOUT: %.loc32: <witness> = complete_type_witness <error> [template = <error>]
File diff suppressed because it is too large Load Diff
+15 -15
View File
@@ -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: <witness> = 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+48, loaded [template = constants.%Derived]
// CHECK:STDOUT: %import_ref.4 = import_ref Main//extend_generic_base, inst+78, unloaded
// CHECK:STDOUT: %Core: <namespace> = 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+44, 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+49, unloaded
// CHECK:STDOUT: %import_ref.10 = import_ref Main//extend_generic_base, inst+61, unloaded
// CHECK:STDOUT: %import_ref.11: type = import_ref Main//extend_generic_base, inst+52, loaded [template = constants.%Base.3]
// CHECK:STDOUT: %import_ref.10 = import_ref Main//extend_generic_base, inst+49, unloaded
// CHECK:STDOUT: %import_ref.11 = import_ref Main//extend_generic_base, inst+61, unloaded
// CHECK:STDOUT: %import_ref.12: type = import_ref Main//extend_generic_base, inst+52, 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: <witness> = 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:
+1 -1
View File
@@ -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 [template]
// CHECK:STDOUT: %.loc6_1.1: <witness> = complete_type_witness %T [symbolic = %.loc6_1.2 (constants.%.1)]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
+8 -8
View File
@@ -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: <witness> = 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+47, loaded [template = constants.%Child]
// CHECK:STDOUT: %Core: <namespace> = 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: %.44 = import_ref Main//a, inst+38, loaded [template = %.1]
// CHECK:STDOUT: %import_ref.7 = import_ref Main//a, inst+43, unloaded
// CHECK:STDOUT: %import_ref.8 = import_ref Main//a, inst+48, unloaded
// CHECK:STDOUT: %import_ref.9 = import_ref Main//a, inst+52, unloaded
// CHECK:STDOUT: %import_ref.10: type = import_ref Main//a, inst+49, loaded [template = constants.%Base]
// CHECK:STDOUT: %import_ref.9 = import_ref Main//a, inst+48, unloaded
// CHECK:STDOUT: %import_ref.10 = import_ref Main//a, inst+52, unloaded
// CHECK:STDOUT: %import_ref.11: type = import_ref Main//a, inst+49, 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 {
+9 -9
View File
@@ -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: %.33 = base_decl %A, element0 [template]
// CHECK:STDOUT: %.loc12: %.33 = 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: <witness> = 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: <witness> = 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
+56 -58
View File
@@ -103,21 +103,20 @@ var e: C = MakeAdaptC();
// CHECK:STDOUT: %.3: type = struct_type {.a: %i32, .b: %i32} [template]
// CHECK:STDOUT: %.4: <witness> = complete_type_witness %.3 [template]
// CHECK:STDOUT: %AdaptC: type = class_type @AdaptC [template]
// CHECK:STDOUT: %.6: <witness> = 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: %.33: <witness> = interface_witness (%Convert.14) [template]
// CHECK:STDOUT: %.34: <bound method> = bound_method %.7, %Convert.14 [template]
// CHECK:STDOUT: %.35: <specific function> = specific_function %.34, @Convert.2(%.1) [template]
// CHECK:STDOUT: %.36: %i32 = int_value 1 [template]
// CHECK:STDOUT: %.37: <bound method> = bound_method %.8, %Convert.14 [template]
// CHECK:STDOUT: %.38: <specific function> = specific_function %.37, @Convert.2(%.1) [template]
// CHECK:STDOUT: %.39: %i32 = int_value 2 [template]
// CHECK:STDOUT: %struct: %C = struct_value (%.36, %.39) [template]
// CHECK:STDOUT: %.32: <witness> = interface_witness (%Convert.14) [template]
// CHECK:STDOUT: %.33: <bound method> = bound_method %.6, %Convert.14 [template]
// CHECK:STDOUT: %.34: <specific function> = specific_function %.33, @Convert.2(%.1) [template]
// CHECK:STDOUT: %.35: %i32 = int_value 1 [template]
// CHECK:STDOUT: %.36: <bound method> = bound_method %.7, %Convert.14 [template]
// CHECK:STDOUT: %.37: <specific function> = specific_function %.36, @Convert.2(%.1) [template]
// CHECK:STDOUT: %.38: %i32 = int_value 2 [template]
// CHECK:STDOUT: %struct: %C = struct_value (%.35, %.38) [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: <witness> = complete_type_witness %C [template = constants.%.6]
// CHECK:STDOUT: adapt_decl %C.ref [template]
// CHECK:STDOUT: %.loc11: <witness> = 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.%.33, element0 [template = constants.%Convert.14]
// CHECK:STDOUT: %.loc13_27.3: <bound method> = bound_method %.loc13_18, %.loc13_27.2 [template = constants.%.34]
// CHECK:STDOUT: %.loc13_27.4: <specific function> = specific_function %.loc13_27.3, @Convert.2(constants.%.1) [template = constants.%.35]
// CHECK:STDOUT: %int.convert_checked.loc13_27.1: init %i32 = call %.loc13_27.4(%.loc13_18) [template = constants.%.36]
// CHECK:STDOUT: %.loc13_27.5: init %i32 = converted %.loc13_18, %int.convert_checked.loc13_27.1 [template = constants.%.36]
// 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.%.32, element0 [template = constants.%Convert.14]
// CHECK:STDOUT: %.loc13_27.3: <bound method> = bound_method %.loc13_18, %.loc13_27.2 [template = constants.%.33]
// CHECK:STDOUT: %.loc13_27.4: <specific function> = specific_function %.loc13_27.3, @Convert.2(constants.%.1) [template = constants.%.34]
// CHECK:STDOUT: %int.convert_checked.loc13_27.1: init %i32 = call %.loc13_27.4(%.loc13_18) [template = constants.%.35]
// CHECK:STDOUT: %.loc13_27.5: init %i32 = converted %.loc13_18, %int.convert_checked.loc13_27.1 [template = constants.%.35]
// 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.%.36]
// CHECK:STDOUT: %.loc13_27.9: %Convert.type.2 = interface_witness_access constants.%.33, element0 [template = constants.%Convert.14]
// CHECK:STDOUT: %.loc13_27.10: <bound method> = bound_method %.loc13_26, %.loc13_27.9 [template = constants.%.37]
// CHECK:STDOUT: %.loc13_27.11: <specific function> = specific_function %.loc13_27.10, @Convert.2(constants.%.1) [template = constants.%.38]
// CHECK:STDOUT: %int.convert_checked.loc13_27.2: init %i32 = call %.loc13_27.11(%.loc13_26) [template = constants.%.39]
// CHECK:STDOUT: %.loc13_27.12: init %i32 = converted %.loc13_26, %int.convert_checked.loc13_27.2 [template = constants.%.39]
// CHECK:STDOUT: %.loc13_27.8: init %i32 = initialize_from %.loc13_27.5 to %.loc13_27.7 [template = constants.%.35]
// CHECK:STDOUT: %.loc13_27.9: %Convert.type.2 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.14]
// CHECK:STDOUT: %.loc13_27.10: <bound method> = bound_method %.loc13_26, %.loc13_27.9 [template = constants.%.36]
// CHECK:STDOUT: %.loc13_27.11: <specific function> = specific_function %.loc13_27.10, @Convert.2(constants.%.1) [template = constants.%.37]
// CHECK:STDOUT: %int.convert_checked.loc13_27.2: init %i32 = call %.loc13_27.11(%.loc13_26) [template = constants.%.38]
// CHECK:STDOUT: %.loc13_27.12: init %i32 = converted %.loc13_26, %int.convert_checked.loc13_27.2 [template = constants.%.38]
// 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.%.39]
// CHECK:STDOUT: %.loc13_27.14: init %i32 = initialize_from %.loc13_27.12 to %.loc13_27.13 [template = constants.%.38]
// 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: <witness> = complete_type_witness %.3 [template]
// CHECK:STDOUT: %AdaptC: type = class_type @AdaptC [template]
// CHECK:STDOUT: %.6: <witness> = 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: %.33: <witness> = interface_witness (%Convert.14) [template]
// CHECK:STDOUT: %.34: <bound method> = bound_method %.7, %Convert.14 [template]
// CHECK:STDOUT: %.35: <specific function> = specific_function %.34, @Convert.2(%.1) [template]
// CHECK:STDOUT: %.36: %i32 = int_value 1 [template]
// CHECK:STDOUT: %.37: <bound method> = bound_method %.8, %Convert.14 [template]
// CHECK:STDOUT: %.38: <specific function> = specific_function %.37, @Convert.2(%.1) [template]
// CHECK:STDOUT: %.39: %i32 = int_value 2 [template]
// CHECK:STDOUT: %struct: %C = struct_value (%.36, %.39) [template]
// CHECK:STDOUT: %.32: <witness> = interface_witness (%Convert.14) [template]
// CHECK:STDOUT: %.33: <bound method> = bound_method %.6, %Convert.14 [template]
// CHECK:STDOUT: %.34: <specific function> = specific_function %.33, @Convert.2(%.1) [template]
// CHECK:STDOUT: %.35: %i32 = int_value 1 [template]
// CHECK:STDOUT: %.36: <bound method> = bound_method %.7, %Convert.14 [template]
// CHECK:STDOUT: %.37: <specific function> = specific_function %.36, @Convert.2(%.1) [template]
// CHECK:STDOUT: %.38: %i32 = int_value 2 [template]
// CHECK:STDOUT: %struct: %C = struct_value (%.35, %.38) [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: <witness> = complete_type_witness %C [template = constants.%.6]
// CHECK:STDOUT: adapt_decl %C.ref [template]
// CHECK:STDOUT: %.loc11: <witness> = 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.%.33, element0 [template = constants.%Convert.14]
// CHECK:STDOUT: %.loc13_27.3: <bound method> = bound_method %.loc13_18, %.loc13_27.2 [template = constants.%.34]
// CHECK:STDOUT: %.loc13_27.4: <specific function> = specific_function %.loc13_27.3, @Convert.2(constants.%.1) [template = constants.%.35]
// CHECK:STDOUT: %int.convert_checked.loc13_27.1: init %i32 = call %.loc13_27.4(%.loc13_18) [template = constants.%.36]
// CHECK:STDOUT: %.loc13_27.5: init %i32 = converted %.loc13_18, %int.convert_checked.loc13_27.1 [template = constants.%.36]
// 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.%.32, element0 [template = constants.%Convert.14]
// CHECK:STDOUT: %.loc13_27.3: <bound method> = bound_method %.loc13_18, %.loc13_27.2 [template = constants.%.33]
// CHECK:STDOUT: %.loc13_27.4: <specific function> = specific_function %.loc13_27.3, @Convert.2(constants.%.1) [template = constants.%.34]
// CHECK:STDOUT: %int.convert_checked.loc13_27.1: init %i32 = call %.loc13_27.4(%.loc13_18) [template = constants.%.35]
// CHECK:STDOUT: %.loc13_27.5: init %i32 = converted %.loc13_18, %int.convert_checked.loc13_27.1 [template = constants.%.35]
// 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.%.36]
// CHECK:STDOUT: %.loc13_27.9: %Convert.type.2 = interface_witness_access constants.%.33, element0 [template = constants.%Convert.14]
// CHECK:STDOUT: %.loc13_27.10: <bound method> = bound_method %.loc13_26, %.loc13_27.9 [template = constants.%.37]
// CHECK:STDOUT: %.loc13_27.11: <specific function> = specific_function %.loc13_27.10, @Convert.2(constants.%.1) [template = constants.%.38]
// CHECK:STDOUT: %int.convert_checked.loc13_27.2: init %i32 = call %.loc13_27.11(%.loc13_26) [template = constants.%.39]
// CHECK:STDOUT: %.loc13_27.12: init %i32 = converted %.loc13_26, %int.convert_checked.loc13_27.2 [template = constants.%.39]
// CHECK:STDOUT: %.loc13_27.8: init %i32 = initialize_from %.loc13_27.5 to %.loc13_27.7 [template = constants.%.35]
// CHECK:STDOUT: %.loc13_27.9: %Convert.type.2 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.14]
// CHECK:STDOUT: %.loc13_27.10: <bound method> = bound_method %.loc13_26, %.loc13_27.9 [template = constants.%.36]
// CHECK:STDOUT: %.loc13_27.11: <specific function> = specific_function %.loc13_27.10, @Convert.2(constants.%.1) [template = constants.%.37]
// CHECK:STDOUT: %int.convert_checked.loc13_27.2: init %i32 = call %.loc13_27.11(%.loc13_26) [template = constants.%.38]
// CHECK:STDOUT: %.loc13_27.12: init %i32 = converted %.loc13_26, %int.convert_checked.loc13_27.2 [template = constants.%.38]
// 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.%.39]
// CHECK:STDOUT: %.loc13_27.14: init %i32 = initialize_from %.loc13_27.12 to %.loc13_27.13 [template = constants.%.38]
// 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
+1 -1
View File
@@ -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
+5 -5
View File
@@ -219,7 +219,7 @@ class Derived {
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] {} {}
// CHECK:STDOUT: %Modifiers.ref: <namespace> = 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: <witness> = complete_type_witness %.6 [template = constants.%.7]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
@@ -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: <witness> = 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: <witness> = 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: <witness> = complete_type_witness %.11 [template = constants.%.12]
// CHECK:STDOUT:
@@ -660,7 +660,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: %.4 = base_decl %Base, element1 [template]
// CHECK:STDOUT: %.loc8: %.4 = base_decl %Base.ref, element1 [template]
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] {} {}
// CHECK:STDOUT: %.loc10: <witness> = complete_type_witness %.6 [template = constants.%.7]
// CHECK:STDOUT:
+3 -3
View File
@@ -565,7 +565,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]
@@ -703,7 +703,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]
@@ -866,7 +866,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]
+30 -39
View File
@@ -99,30 +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 <typename InstT>
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 <typename InstT>
requires(InstT::Kind.is_type() == SemIR::InstIsType::Always &&
InstT::Kind.constant_kind() != SemIR::InstConstantKind::SymbolicOnly)
static auto EmitAsConstant(ConstantContext& context, InstT /*inst*/)
-> llvm::Constant* {
return context.GetTypeAsValue();
}
// Represent facet values the same as types.
static auto EmitAsConstant(ConstantContext& context, SemIR::FacetValue /*inst*/)
-> llvm::Constant* {
@@ -197,20 +179,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);
@@ -226,7 +194,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));
}
@@ -246,6 +215,28 @@ 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 <typename InstT>
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) {
// All types are lowered to the same value.
return context.GetTypeAsValue();
} else {
return EmitAsConstant(context, inst);
}
}
auto LowerConstants(FileContext& file_context,
llvm::MutableArrayRef<llvm::Constant*> constants) -> void {
ConstantContext context(file_context, constants);
@@ -273,10 +264,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"
}
+1 -4
View File
@@ -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<SemIR::ClassType>(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.
+1
View File
@@ -74,6 +74,7 @@ cc_library(
"generic.cpp",
"impl.cpp",
"name.cpp",
"type.cpp",
"type_info.cpp",
],
hdrs = [
+24
View File
@@ -7,9 +7,33 @@
#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 {
static auto GetFoundationType(const File& file, SpecificId specific_id,
InstId inst_id) -> TypeId {
if (!inst_id.is_valid()) {
return TypeId::Invalid;
}
if (inst_id == SemIR::InstId::BuiltinErrorInst) {
return TypeId::Error;
}
return TypeId::ForTypeConstant(GetConstantValueInSpecific(
file, specific_id,
file.insts().GetAs<AnyFoundationDecl>(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 {
return GetFoundationType(file, specific_id, base_id);
}
auto Class::GetObjectRepr(const File& file, SpecificId specific_id) const
-> TypeId {
if (!complete_type_witness_id.is_valid()) {
+8
View File
@@ -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;
+1 -25
View File
@@ -37,12 +37,6 @@ namespace Carbon::SemIR {
// Provides semantic analysis on a Parse::Tree.
class File : public Printable<File> {
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,
const std::optional<Parse::Tree::PackagingDecl>& packaging_decl,
@@ -79,24 +73,6 @@ class File : public Printable<File> {
return types().GetAs<PointerType>(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<IntType>(inst_id);
auto bit_width_inst = insts().TryGetAs<IntValue>(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_; }
@@ -293,7 +269,7 @@ class File : public Printable<File> {
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
+66
View File
@@ -0,0 +1,66 @@
// 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 {
type_id = GetUnqualifiedType(type_id);
auto class_type = TryGetAs<ClassType>(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::GetUnqualifiedType(TypeId type_id) const -> TypeId {
if (auto const_type = TryGetAs<ConstType>(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()) {
return false;
}
auto inst_id = GetInstId(int_type_id);
if (inst_id == InstId::BuiltinIntLiteralType) {
return true;
}
auto int_type = file_->insts().TryGetAs<IntType>(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<IntType>(inst_id);
auto bit_width_inst =
file_->insts().TryGetAs<IntValue>(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
+30 -21
View File
@@ -16,8 +16,13 @@ namespace Carbon::SemIR {
// Provides a ValueStore wrapper with an API specific to types.
class TypeStore : public Yaml::Printable<TypeStore> {
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<TypeStore> {
}
// 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<TypeStore> {
// to be a particular kind of instruction.
template <typename InstT>
auto GetAs(TypeId type_id) const -> InstT {
auto inst_id = constants_->GetInstId(GetConstantId(type_id));
return insts_->GetAs<InstT>(inst_id);
return GetAsInst(type_id).As<InstT>();
}
// Returns the instruction used to define the specified type, if it is of a
@@ -87,21 +87,31 @@ class TypeStore : public Yaml::Printable<TypeStore> {
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<IntType>(inst_id);
return int_type && int_type->int_kind.is_signed();
}
// 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.
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 +138,7 @@ class TypeStore : public Yaml::Printable<TypeStore> {
}
private:
InstStore* insts_;
ConstantValueStore* constants_;
File* file_;
Map<TypeId, CompleteTypeInfo> complete_type_info_;
llvm::SmallVector<TypeId> complete_types_;
};
+18 -3
View File
@@ -72,13 +72,26 @@ struct BoolType {
TypeId type_id;
};
// 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<Parse::AdaptDeclId>(
{.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.
TypeId adapted_type_id;
InstId adapted_type_inst_id;
};
// Takes the address of a reference expression, such as for the `&` address-of
@@ -242,7 +255,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;
};
@@ -846,6 +859,8 @@ struct InterfaceWitness {
static constexpr auto Kind = InstKind::InterfaceWitness.Define<Parse::NodeId>(
{.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.