mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 12:11:04 +01:00
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:
co-authored by
Jon Ross-Perkins
parent
e0db74a2a1
commit
d6ec885eb3
+20
-22
@@ -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";
|
||||
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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>(
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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]
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
@@ -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:
|
||||
|
||||
@@ -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
@@ -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>]
|
||||
|
||||
+1008
File diff suppressed because it is too large
Load Diff
+15
-15
@@ -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
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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]
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -74,6 +74,7 @@ cc_library(
|
||||
"generic.cpp",
|
||||
"impl.cpp",
|
||||
"name.cpp",
|
||||
"type.cpp",
|
||||
"type_info.cpp",
|
||||
],
|
||||
hdrs = [
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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_;
|
||||
};
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user