mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 19:10:14 +01:00
Facet member access (#4371)
Adds `FacetAccessWitness` instruction and uses it in `member_access.cpp` to support accessing members of facets. Still to do: interface witness access is producing runtime values when it should produce symbolic values. --------- Co-authored-by: Josh L <josh11b@users.noreply.github.com>
This commit is contained in:
@@ -1627,7 +1627,21 @@ static auto TryEvalInstInContext(EvalContext& eval_context,
|
||||
return MakeNonConstantResult(phase);
|
||||
}
|
||||
}
|
||||
|
||||
case CARBON_KIND(SemIR::FacetAccessWitness typed_inst): {
|
||||
Phase phase = Phase::Template;
|
||||
if (ReplaceFieldWithConstantValue(
|
||||
eval_context, &typed_inst,
|
||||
&SemIR::FacetAccessWitness::facet_value_inst_id, &phase)) {
|
||||
if (auto facet_value = eval_context.insts().TryGetAs<SemIR::FacetValue>(
|
||||
typed_inst.facet_value_inst_id)) {
|
||||
return eval_context.constant_values().Get(
|
||||
facet_value->witness_inst_id);
|
||||
}
|
||||
return MakeConstantResult(eval_context.context(), typed_inst, phase);
|
||||
} else {
|
||||
return MakeNonConstantResult(phase);
|
||||
}
|
||||
}
|
||||
case CARBON_KIND(SemIR::WhereExpr typed_inst): {
|
||||
Phase phase = Phase::Template;
|
||||
SemIR::TypeId base_facet_type_id =
|
||||
|
||||
@@ -124,6 +124,46 @@ static auto ScopeNeedsImplLookup(Context& context,
|
||||
return true;
|
||||
}
|
||||
|
||||
static auto GetInterfaceFromFacetType(Context& context, SemIR::TypeId type_id)
|
||||
-> std::optional<SemIR::FacetTypeInfo::ImplsConstraint> {
|
||||
auto facet_type = context.types().GetAs<SemIR::FacetType>(type_id);
|
||||
const auto& facet_type_info =
|
||||
context.facet_types().Get(facet_type.facet_type_id);
|
||||
return facet_type_info.TryAsSingleInterface();
|
||||
}
|
||||
|
||||
static auto AccessMemberOfInterfaceWitness(
|
||||
Context& context, SemIR::LocId loc_id, SemIR::InstId witness_id,
|
||||
SemIR::SpecificId interface_specific_id,
|
||||
SemIR::AssociatedEntityType assoc_type, SemIR::InstId member_id)
|
||||
-> SemIR::InstId {
|
||||
auto member_value_id = context.constant_values().GetConstantInstId(member_id);
|
||||
if (!member_value_id.is_valid()) {
|
||||
if (member_value_id != SemIR::InstId::BuiltinErrorInst) {
|
||||
context.TODO(member_id, "non-constant associated entity");
|
||||
}
|
||||
return SemIR::InstId::BuiltinErrorInst;
|
||||
}
|
||||
|
||||
auto assoc_entity =
|
||||
context.insts().TryGetAs<SemIR::AssociatedEntity>(member_value_id);
|
||||
if (!assoc_entity) {
|
||||
context.TODO(member_id, "unexpected value for associated entity");
|
||||
return SemIR::InstId::BuiltinErrorInst;
|
||||
}
|
||||
|
||||
// TODO: This produces the type of the associated entity with no value for
|
||||
// `Self`. The type `Self` might appear in the type of an associated constant,
|
||||
// and if so, we'll need to substitute it here somehow.
|
||||
auto subst_type_id = SemIR::GetTypeInSpecific(
|
||||
context.sem_ir(), interface_specific_id, assoc_type.entity_type_id);
|
||||
|
||||
return context.GetOrAddInst<SemIR::InterfaceWitnessAccess>(
|
||||
loc_id, {.type_id = subst_type_id,
|
||||
.witness_id = witness_id,
|
||||
.index = assoc_entity->index});
|
||||
}
|
||||
|
||||
// Performs impl lookup for a member name expression. This finds the relevant
|
||||
// impl witness and extracts the corresponding impl member.
|
||||
static auto PerformImplLookup(
|
||||
@@ -131,11 +171,8 @@ static auto PerformImplLookup(
|
||||
SemIR::AssociatedEntityType assoc_type, SemIR::InstId member_id,
|
||||
Context::BuildDiagnosticFn missing_impl_diagnoser = nullptr)
|
||||
-> SemIR::InstId {
|
||||
auto facet_type =
|
||||
context.types().GetAs<SemIR::FacetType>(assoc_type.interface_type_id);
|
||||
const auto& facet_type_info =
|
||||
context.facet_types().Get(facet_type.facet_type_id);
|
||||
auto interface_type = facet_type_info.TryAsSingleInterface();
|
||||
auto interface_type =
|
||||
GetInterfaceFromFacetType(context, assoc_type.interface_type_id);
|
||||
if (!interface_type) {
|
||||
context.TODO(loc_id,
|
||||
"Lookup of impl witness not yet supported except for a single "
|
||||
@@ -170,42 +207,20 @@ static auto PerformImplLookup(
|
||||
}
|
||||
return SemIR::InstId::BuiltinErrorInst;
|
||||
}
|
||||
|
||||
auto member_value_id = context.constant_values().GetConstantInstId(member_id);
|
||||
if (!member_value_id.is_valid()) {
|
||||
if (member_value_id != SemIR::InstId::BuiltinErrorInst) {
|
||||
context.TODO(member_id, "non-constant associated entity");
|
||||
}
|
||||
return SemIR::InstId::BuiltinErrorInst;
|
||||
}
|
||||
|
||||
auto assoc_entity =
|
||||
context.insts().TryGetAs<SemIR::AssociatedEntity>(member_value_id);
|
||||
if (!assoc_entity) {
|
||||
context.TODO(member_id, "unexpected value for associated entity");
|
||||
return SemIR::InstId::BuiltinErrorInst;
|
||||
}
|
||||
|
||||
// TODO: This produces the type of the associated entity with no value for
|
||||
// `Self`. The type `Self` might appear in the type of an associated constant,
|
||||
// and if so, we'll need to substitute it here somehow.
|
||||
auto subst_type_id = SemIR::GetTypeInSpecific(
|
||||
context.sem_ir(), interface_type->specific_id, assoc_type.entity_type_id);
|
||||
|
||||
return context.GetOrAddInst<SemIR::InterfaceWitnessAccess>(
|
||||
loc_id, {.type_id = subst_type_id,
|
||||
.witness_id = witness_id,
|
||||
.index = assoc_entity->index});
|
||||
return AccessMemberOfInterfaceWitness(context, loc_id, witness_id,
|
||||
interface_type->specific_id, assoc_type,
|
||||
member_id);
|
||||
}
|
||||
|
||||
// Performs a member name lookup into the specified scope, including performing
|
||||
// impl lookup if necessary. If the scope is invalid, assume an error has
|
||||
// already been diagnosed, and return BuiltinErrorInst.
|
||||
static auto LookupMemberNameInScope(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::InstId /*base_id*/,
|
||||
SemIR::InstId base_id,
|
||||
SemIR::NameId name_id,
|
||||
SemIR::ConstantId name_scope_const_id,
|
||||
llvm::ArrayRef<LookupScope> lookup_scopes)
|
||||
llvm::ArrayRef<LookupScope> lookup_scopes,
|
||||
bool lookup_in_type_of_base)
|
||||
-> SemIR::InstId {
|
||||
AccessInfo access_info = {
|
||||
.constant_id = name_scope_const_id,
|
||||
@@ -250,7 +265,64 @@ static auto LookupMemberNameInScope(Context& context, SemIR::LocId loc_id,
|
||||
// impl member is not supposed to be treated as ambiguous.
|
||||
if (auto assoc_type =
|
||||
context.types().TryGetAs<SemIR::AssociatedEntityType>(type_id)) {
|
||||
if (ScopeNeedsImplLookup(context, name_scope_const_id)) {
|
||||
if (lookup_in_type_of_base) {
|
||||
SemIR::TypeId base_type_id = context.insts().Get(base_id).type_id();
|
||||
if (base_type_id != SemIR::TypeId::TypeType &&
|
||||
context.IsFacetType(base_type_id)) {
|
||||
// Handles `T.F` when `T` is a non-type facet.
|
||||
|
||||
auto assoc_interface =
|
||||
GetInterfaceFromFacetType(context, assoc_type->interface_type_id);
|
||||
// An associated entity should always be associated with a single
|
||||
// interface.
|
||||
CARBON_CHECK(assoc_interface);
|
||||
|
||||
// First look for `*assoc_interface` in the type of the base. If it is
|
||||
// found, get the witness that the interface is implemented from
|
||||
// `base_id`.
|
||||
auto facet_type = context.types().GetAs<SemIR::FacetType>(base_type_id);
|
||||
const auto& facet_type_info =
|
||||
context.facet_types().Get(facet_type.facet_type_id);
|
||||
// Witness that `T` implements the `*assoc_interface`.
|
||||
SemIR::InstId witness_inst_id = SemIR::InstId::Invalid;
|
||||
for (auto base_interface : facet_type_info.impls_constraints) {
|
||||
// Get the witness that `T` implements `base_type_id`.
|
||||
if (base_interface == *assoc_interface) {
|
||||
witness_inst_id = context.GetOrAddInst<SemIR::FacetAccessWitness>(
|
||||
loc_id, {.type_id = context.GetBuiltinType(
|
||||
SemIR::BuiltinInstKind::WitnessType),
|
||||
.facet_value_inst_id = base_id});
|
||||
// TODO: Result will eventually be a facet type witness instead of
|
||||
// an interface witness. Will need to use the index
|
||||
// `*assoc_interface` was found in
|
||||
// `facet_type_info.impls_constraints` to get the correct interface
|
||||
// witness out.
|
||||
break;
|
||||
}
|
||||
}
|
||||
// TODO: If that fails, would need to do impl lookup to see if the facet
|
||||
// value implements the interface of `*assoc_type`.
|
||||
if (!witness_inst_id.is_valid()) {
|
||||
context.TODO(member_id,
|
||||
"associated entity not found in facet type, need to do "
|
||||
"impl lookup");
|
||||
return SemIR::InstId::BuiltinErrorInst;
|
||||
}
|
||||
|
||||
member_id = AccessMemberOfInterfaceWitness(
|
||||
context, loc_id, witness_inst_id, assoc_interface->specific_id,
|
||||
*assoc_type, member_id);
|
||||
} else {
|
||||
// Handles `x.F` if `x` is of type `class C` that extends an interface
|
||||
// containing `F`.
|
||||
SemIR::ConstantId constant_id =
|
||||
context.types().GetConstantId(base_type_id);
|
||||
member_id = PerformImplLookup(context, loc_id, constant_id, *assoc_type,
|
||||
member_id);
|
||||
}
|
||||
} else if (ScopeNeedsImplLookup(context, name_scope_const_id)) {
|
||||
// Handles `T.F` where `T` is a type extending an interface containing
|
||||
// `F`.
|
||||
member_id = PerformImplLookup(context, loc_id, name_scope_const_id,
|
||||
*assoc_type, member_id);
|
||||
}
|
||||
@@ -342,7 +414,8 @@ auto PerformMemberAccess(Context& context, SemIR::LocId loc_id,
|
||||
if (context.AppendLookupScopesForConstant(loc_id, base_const_id,
|
||||
&lookup_scopes)) {
|
||||
return LookupMemberNameInScope(context, loc_id, base_id, name_id,
|
||||
base_const_id, lookup_scopes);
|
||||
base_const_id, lookup_scopes,
|
||||
/*lookup_in_type_of_base=*/false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -401,7 +474,8 @@ auto PerformMemberAccess(Context& context, SemIR::LocId loc_id,
|
||||
|
||||
// Perform lookup into the base type.
|
||||
auto member_id = LookupMemberNameInScope(context, loc_id, base_id, name_id,
|
||||
base_type_const_id, lookup_scopes);
|
||||
base_type_const_id, lookup_scopes,
|
||||
/*lookup_in_type_of_base=*/true);
|
||||
|
||||
// Perform instance binding if we found an instance member.
|
||||
member_id = PerformInstanceBinding(context, loc_id, base_id, member_id);
|
||||
|
||||
+17
-21
@@ -10,35 +10,28 @@
|
||||
|
||||
interface I { let T:! type; }
|
||||
|
||||
// CHECK:STDERR: fail_todo_impl_assoc_const.carbon:[[@LINE+10]]:1: error: semantics TODO: `impl of interface with associated constant` [SemanticsTodo]
|
||||
// CHECK:STDERR: fail_todo_impl_assoc_const.carbon:[[@LINE+3]]:1: error: semantics TODO: `impl of interface with associated constant` [SemanticsTodo]
|
||||
// CHECK:STDERR: impl bool as I where .T = bool {}
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: fail_todo_impl_assoc_const.carbon:[[@LINE+6]]:27: error: cannot implicitly convert from `type` to `<associated type in I>` [ImplicitAsConversionFailure]
|
||||
// CHECK:STDERR: impl bool as I where .T = bool {}
|
||||
// CHECK:STDERR: ^~~~
|
||||
// CHECK:STDERR: fail_todo_impl_assoc_const.carbon:[[@LINE+3]]:27: note: type `type` does not implement interface `ImplicitAs(<associated type in I>)` [MissingImplInMemberAccessNote]
|
||||
// CHECK:STDERR: impl bool as I where .T = bool {}
|
||||
// CHECK:STDERR: ^~~~
|
||||
impl bool as I where .T = bool {}
|
||||
|
||||
// CHECK:STDOUT: --- fail_todo_impl_assoc_const.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %I.type.1: type = facet_type <@I> [template]
|
||||
// CHECK:STDOUT: %Self.1: %I.type.1 = bind_symbolic_name Self, 0 [symbolic]
|
||||
// CHECK:STDOUT: %Self: %I.type.1 = bind_symbolic_name Self, 0 [symbolic]
|
||||
// CHECK:STDOUT: %.1: type = assoc_entity_type %I.type.1, type [template]
|
||||
// CHECK:STDOUT: %.2: %.1 = assoc_entity element0, @I.%T [template]
|
||||
// CHECK:STDOUT: %Bool.type: type = fn_type @Bool [template]
|
||||
// CHECK:STDOUT: %Bool: %Bool.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.Self: %I.type.1 = bind_symbolic_name .Self, 0 [symbolic]
|
||||
// CHECK:STDOUT: %.3: <witness> = facet_access_witness %.Self [symbolic]
|
||||
// CHECK:STDOUT: %I.type.2: type = facet_type <@I where TODO> [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [template] {
|
||||
// CHECK:STDOUT: .Bool = %import_ref.1
|
||||
// CHECK:STDOUT: .ImplicitAs = %import_ref.2
|
||||
// CHECK:STDOUT: .Bool = %import_ref
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/...
|
||||
// CHECK:STDOUT: }
|
||||
@@ -51,24 +44,27 @@ impl bool as I where .T = bool {}
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Core.import = import Core
|
||||
// CHECK:STDOUT: %I.decl: type = interface_decl @I [template = constants.%I.type.1] {} {}
|
||||
// CHECK:STDOUT: impl_decl @impl.9 [template] {} {
|
||||
// CHECK:STDOUT: %bool.make_type.loc23_6: init type = call constants.%Bool() [template = bool]
|
||||
// CHECK:STDOUT: %.loc23_6.1: type = value_of_initializer %bool.make_type.loc23_6 [template = bool]
|
||||
// CHECK:STDOUT: %.loc23_6.2: type = converted %bool.make_type.loc23_6, %.loc23_6.1 [template = bool]
|
||||
// CHECK:STDOUT: impl_decl @impl [template] {} {
|
||||
// CHECK:STDOUT: %bool.make_type.loc16_6: init type = call constants.%Bool() [template = bool]
|
||||
// CHECK:STDOUT: %.loc16_6.1: type = value_of_initializer %bool.make_type.loc16_6 [template = bool]
|
||||
// CHECK:STDOUT: %.loc16_6.2: type = converted %bool.make_type.loc16_6, %.loc16_6.1 [template = bool]
|
||||
// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [template = constants.%I.type.1]
|
||||
// CHECK:STDOUT: %.Self: %I.type.1 = bind_symbolic_name .Self, 0 [symbolic = constants.%.Self]
|
||||
// CHECK:STDOUT: %.Self.ref: %I.type.1 = name_ref .Self, %.Self [symbolic = constants.%.Self]
|
||||
// CHECK:STDOUT: %T.ref: %.1 = name_ref T, @I.%.loc11 [template = constants.%.2]
|
||||
// CHECK:STDOUT: %bool.make_type.loc23_27: init type = call constants.%Bool() [template = bool]
|
||||
// CHECK:STDOUT: %.loc23_27: %.1 = converted %bool.make_type.loc23_27, <error> [template = <error>]
|
||||
// CHECK:STDOUT: %.loc23_16: type = where_expr %.Self [template = constants.%I.type.2] {
|
||||
// CHECK:STDOUT: requirement_rewrite %T.ref, <error>
|
||||
// CHECK:STDOUT: %.loc16_22.1: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.3]
|
||||
// CHECK:STDOUT: %.loc16_22.2: type = interface_witness_access %.loc16_22.1, element0
|
||||
// CHECK:STDOUT: %bool.make_type.loc16_27: init type = call constants.%Bool() [template = bool]
|
||||
// CHECK:STDOUT: %.loc16_27.1: type = value_of_initializer %bool.make_type.loc16_27 [template = bool]
|
||||
// CHECK:STDOUT: %.loc16_27.2: type = converted %bool.make_type.loc16_27, %.loc16_27.1 [template = bool]
|
||||
// CHECK:STDOUT: %.loc16_16: type = where_expr %.Self [template = constants.%I.type.2] {
|
||||
// CHECK:STDOUT: requirement_rewrite %.loc16_22.2, %.loc16_27.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: interface @I {
|
||||
// CHECK:STDOUT: %Self: %I.type.1 = bind_symbolic_name Self, 0 [symbolic = constants.%Self.1]
|
||||
// CHECK:STDOUT: %Self: %I.type.1 = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
|
||||
// CHECK:STDOUT: %T: type = assoc_const_decl T [template]
|
||||
// CHECK:STDOUT: %.loc11: %.1 = assoc_entity element0, %T [template = constants.%.2]
|
||||
// CHECK:STDOUT:
|
||||
@@ -78,7 +74,7 @@ impl bool as I where .T = bool {}
|
||||
// CHECK:STDOUT: witness = (%T)
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: impl @impl.9: %.loc23_6.2 as %.loc23_16 {
|
||||
// CHECK:STDOUT: impl @impl: %.loc16_6.2 as %.loc16_16 {
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: witness = <error>
|
||||
// CHECK:STDOUT: }
|
||||
|
||||
@@ -21,17 +21,25 @@ fn F() {
|
||||
// CHECK:STDERR:
|
||||
Interface.F();
|
||||
|
||||
// CHECK:STDERR: fail_member_lookup.carbon:[[@LINE+3]]:10: error: `Core.ImplicitAs` implicitly referenced here, but package `Core` not found [CoreNotFound]
|
||||
// CHECK:STDERR: fail_member_lookup.carbon:[[@LINE+4]]:10: error: `Core.ImplicitAs` implicitly referenced here, but package `Core` not found [CoreNotFound]
|
||||
// CHECK:STDERR: var v: Interface.T;
|
||||
// CHECK:STDERR: ^~~~~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
var v: Interface.T;
|
||||
}
|
||||
|
||||
interface Different {}
|
||||
|
||||
// CHECK:STDERR: fail_member_lookup.carbon:[[@LINE+3]]:24: error: cannot access member of interface `Interface` in type `Different` that does not implement that interface [MissingImplInMemberAccess]
|
||||
// CHECK:STDERR: fn G(U:! Different) -> U.(Interface.T);
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~
|
||||
fn G(U:! Different) -> U.(Interface.T);
|
||||
|
||||
// CHECK:STDOUT: --- fail_member_lookup.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %Interface.type: type = facet_type <@Interface> [template]
|
||||
// CHECK:STDOUT: %Self: %Interface.type = bind_symbolic_name Self, 0 [symbolic]
|
||||
// CHECK:STDOUT: %Self.1: %Interface.type = bind_symbolic_name Self, 0 [symbolic]
|
||||
// CHECK:STDOUT: %F.type.1: type = fn_type @F.1 [template]
|
||||
// CHECK:STDOUT: %F.1: %F.type.1 = struct_value () [template]
|
||||
// CHECK:STDOUT: %.1: type = assoc_entity_type %Interface.type, %F.type.1 [template]
|
||||
@@ -40,19 +48,43 @@ fn F() {
|
||||
// CHECK:STDOUT: %.4: %.3 = assoc_entity element1, @Interface.%T [template]
|
||||
// CHECK:STDOUT: %F.type.2: type = fn_type @F.2 [template]
|
||||
// CHECK:STDOUT: %F.2: %F.type.2 = struct_value () [template]
|
||||
// CHECK:STDOUT: %Different.type: type = facet_type <@Different> [template]
|
||||
// CHECK:STDOUT: %Self.2: %Different.type = bind_symbolic_name Self, 0 [symbolic]
|
||||
// CHECK:STDOUT: %U: %Different.type = bind_symbolic_name U, 0 [symbolic]
|
||||
// CHECK:STDOUT: %U.patt: %Different.type = symbolic_binding_pattern U, 0 [symbolic]
|
||||
// CHECK:STDOUT: %G.type: type = fn_type @G [template]
|
||||
// CHECK:STDOUT: %G: %G.type = struct_value () [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [template] {
|
||||
// CHECK:STDOUT: .Interface = %Interface.decl
|
||||
// CHECK:STDOUT: .F = %F.decl
|
||||
// CHECK:STDOUT: .Different = %Different.decl
|
||||
// CHECK:STDOUT: .G = %G.decl
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Interface.decl: type = interface_decl @Interface [template = constants.%Interface.type] {} {}
|
||||
// CHECK:STDOUT: %F.decl: %F.type.2 = fn_decl @F.2 [template = constants.%F.2] {} {}
|
||||
// CHECK:STDOUT: %Different.decl: type = interface_decl @Different [template = constants.%Different.type] {} {}
|
||||
// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [template = constants.%G] {
|
||||
// CHECK:STDOUT: %U.patt.loc36_6.1: %Different.type = symbolic_binding_pattern U, 0 [symbolic = %U.patt.loc36_6.2 (constants.%U.patt)]
|
||||
// CHECK:STDOUT: %U.param_patt: %Different.type = value_param_pattern %U.patt.loc36_6.1, runtime_param<invalid> [symbolic = %U.patt.loc36_6.2 (constants.%U.patt)]
|
||||
// CHECK:STDOUT: %return.patt: <error> = return_slot_pattern
|
||||
// CHECK:STDOUT: %return.param_patt: <error> = out_param_pattern %return.patt, runtime_param0
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %Different.ref: type = name_ref Different, file.%Different.decl [template = constants.%Different.type]
|
||||
// CHECK:STDOUT: %U.ref: %Different.type = name_ref U, %U.loc36_6.1 [symbolic = %U.loc36_6.2 (constants.%U)]
|
||||
// CHECK:STDOUT: %Interface.ref: type = name_ref Interface, file.%Interface.decl [template = constants.%Interface.type]
|
||||
// CHECK:STDOUT: %T.ref: %.3 = name_ref T, @Interface.%.loc14 [template = constants.%.4]
|
||||
// CHECK:STDOUT: %U.param: %Different.type = value_param runtime_param<invalid>
|
||||
// CHECK:STDOUT: %U.loc36_6.1: %Different.type = bind_symbolic_name U, 0, %U.param [symbolic = %U.loc36_6.2 (constants.%U)]
|
||||
// CHECK:STDOUT: %return.param: ref <error> = out_param runtime_param0
|
||||
// CHECK:STDOUT: %return: ref <error> = return_slot %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: interface @Interface {
|
||||
// CHECK:STDOUT: %Self: %Interface.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
|
||||
// CHECK:STDOUT: %Self: %Interface.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.1]
|
||||
// CHECK:STDOUT: %F.decl: %F.type.1 = fn_decl @F.1 [template = constants.%F.1] {} {}
|
||||
// CHECK:STDOUT: %.loc12: %.1 = assoc_entity element0, %F.decl [template = constants.%.2]
|
||||
// CHECK:STDOUT: %T: type = assoc_const_decl T [template]
|
||||
@@ -65,6 +97,14 @@ fn F() {
|
||||
// CHECK:STDOUT: witness = (%F.decl, %T)
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: interface @Different {
|
||||
// CHECK:STDOUT: %Self: %Different.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.2]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = %Self
|
||||
// CHECK:STDOUT: witness = ()
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic fn @F.1(@Interface.%Self: %Interface.type) {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn();
|
||||
@@ -74,13 +114,25 @@ fn F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Interface.ref.loc22: type = name_ref Interface, file.%Interface.decl [template = constants.%Interface.type]
|
||||
// CHECK:STDOUT: %F.ref: %.1 = name_ref F, @Interface.%.loc12 [template = constants.%.2]
|
||||
// CHECK:STDOUT: %Interface.ref.loc27: type = name_ref Interface, file.%Interface.decl [template = constants.%Interface.type]
|
||||
// CHECK:STDOUT: %Interface.ref.loc28: type = name_ref Interface, file.%Interface.decl [template = constants.%Interface.type]
|
||||
// CHECK:STDOUT: %T.ref: %.3 = name_ref T, @Interface.%.loc14 [template = constants.%.4]
|
||||
// CHECK:STDOUT: %.loc27: type = converted %T.ref, <error> [template = <error>]
|
||||
// CHECK:STDOUT: %.loc28: type = converted %T.ref, <error> [template = <error>]
|
||||
// CHECK:STDOUT: %v.var: ref <error> = var v
|
||||
// CHECK:STDOUT: %v: ref <error> = bind_name v, %v.var
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F.1(constants.%Self) {}
|
||||
// CHECK:STDOUT: generic fn @G(%U.loc36_6.1: %Different.type) {
|
||||
// CHECK:STDOUT: %U.loc36_6.2: %Different.type = bind_symbolic_name U, 0 [symbolic = %U.loc36_6.2 (constants.%U)]
|
||||
// CHECK:STDOUT: %U.patt.loc36_6.2: %Different.type = symbolic_binding_pattern U, 0 [symbolic = %U.patt.loc36_6.2 (constants.%U.patt)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%U.param_patt: %Different.type) -> <error>;
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F.1(constants.%Self.1) {}
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @G(constants.%U) {
|
||||
// CHECK:STDOUT: %U.loc36_6.2 => constants.%U
|
||||
// CHECK:STDOUT: %U.patt.loc36_6.2 => constants.%U
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
+16
-12
@@ -11,7 +11,7 @@
|
||||
interface Interface { fn F(); }
|
||||
|
||||
fn CallStatic(T:! Interface) {
|
||||
// CHECK:STDERR: fail_todo_facet_lookup.carbon:[[@LINE+4]]:3: error: value of type `<associated <type of F> in Interface>` is not callable [CallToNonCallable]
|
||||
// CHECK:STDERR: fail_todo_facet_lookup.carbon:[[@LINE+4]]:3: error: value of type `<type of F>` is not callable [CallToNonCallable]
|
||||
// CHECK:STDERR: T.F();
|
||||
// CHECK:STDERR: ^~~~
|
||||
// CHECK:STDERR:
|
||||
@@ -38,7 +38,8 @@ fn CallFacet(T:! Interface, x: T) {
|
||||
// CHECK:STDOUT: %T.patt: %Interface.type = symbolic_binding_pattern T, 0 [symbolic]
|
||||
// CHECK:STDOUT: %CallStatic.type: type = fn_type @CallStatic [template]
|
||||
// CHECK:STDOUT: %CallStatic: %CallStatic.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.3: type = facet_access_type %T [symbolic]
|
||||
// CHECK:STDOUT: %.3: <witness> = facet_access_witness %T [symbolic]
|
||||
// CHECK:STDOUT: %.4: type = facet_access_type %T [symbolic]
|
||||
// CHECK:STDOUT: %CallFacet.type: type = fn_type @CallFacet [template]
|
||||
// CHECK:STDOUT: %CallFacet: %CallFacet.type = struct_value () [template]
|
||||
// CHECK:STDOUT: }
|
||||
@@ -61,17 +62,17 @@ fn CallFacet(T:! Interface, x: T) {
|
||||
// CHECK:STDOUT: %CallFacet.decl: %CallFacet.type = fn_decl @CallFacet [template = constants.%CallFacet] {
|
||||
// CHECK:STDOUT: %T.patt.loc21_14.1: %Interface.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc21_14.2 (constants.%T.patt)]
|
||||
// CHECK:STDOUT: %T.param_patt: %Interface.type = value_param_pattern %T.patt.loc21_14.1, runtime_param<invalid> [symbolic = %T.patt.loc21_14.2 (constants.%T.patt)]
|
||||
// CHECK:STDOUT: %x.patt: @CallFacet.%.loc21_32.3 (%.3) = binding_pattern x
|
||||
// CHECK:STDOUT: %x.param_patt: @CallFacet.%.loc21_32.3 (%.3) = value_param_pattern %x.patt, runtime_param0
|
||||
// CHECK:STDOUT: %x.patt: @CallFacet.%.loc21_32.3 (%.4) = binding_pattern x
|
||||
// CHECK:STDOUT: %x.param_patt: @CallFacet.%.loc21_32.3 (%.4) = value_param_pattern %x.patt, runtime_param0
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %Interface.ref: type = name_ref Interface, file.%Interface.decl [template = constants.%Interface.type]
|
||||
// CHECK:STDOUT: %T.ref: %Interface.type = name_ref T, %T.loc21_14.1 [symbolic = %T.loc21_14.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %.loc21_32.1: type = facet_access_type %T.ref [symbolic = %.loc21_32.3 (constants.%.3)]
|
||||
// CHECK:STDOUT: %.loc21_32.2: type = converted %T.ref, %.loc21_32.1 [symbolic = %.loc21_32.3 (constants.%.3)]
|
||||
// CHECK:STDOUT: %.loc21_32.1: type = facet_access_type %T.ref [symbolic = %.loc21_32.3 (constants.%.4)]
|
||||
// CHECK:STDOUT: %.loc21_32.2: type = converted %T.ref, %.loc21_32.1 [symbolic = %.loc21_32.3 (constants.%.4)]
|
||||
// CHECK:STDOUT: %T.param: %Interface.type = value_param runtime_param<invalid>
|
||||
// CHECK:STDOUT: %T.loc21_14.1: %Interface.type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc21_14.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %x.param: @CallFacet.%.loc21_32.3 (%.3) = value_param runtime_param0
|
||||
// CHECK:STDOUT: %x: @CallFacet.%.loc21_32.3 (%.3) = bind_name x, %x.param
|
||||
// CHECK:STDOUT: %x.param: @CallFacet.%.loc21_32.3 (%.4) = value_param runtime_param0
|
||||
// CHECK:STDOUT: %x: @CallFacet.%.loc21_32.3 (%.4) = bind_name x, %x.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -96,11 +97,14 @@ fn CallFacet(T:! Interface, x: T) {
|
||||
// CHECK:STDOUT: %T.patt.loc13_15.2: %Interface.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc13_15.2 (constants.%T.patt)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc18_4.3: <witness> = facet_access_witness %T.loc13_15.2 [symbolic = %.loc18_4.3 (constants.%.3)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%T.param_patt: %Interface.type) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %T.ref: %Interface.type = name_ref T, %T.loc13_15.1 [symbolic = %T.loc13_15.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %F.ref: %.1 = name_ref F, @Interface.%.loc11 [template = constants.%.2]
|
||||
// CHECK:STDOUT: %.loc18_4.1: <witness> = facet_access_witness %T.ref [symbolic = %.loc18_4.3 (constants.%.3)]
|
||||
// CHECK:STDOUT: %.loc18_4.2: %F.type = interface_witness_access %.loc18_4.1, element0
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
@@ -108,13 +112,13 @@ fn CallFacet(T:! Interface, x: T) {
|
||||
// CHECK:STDOUT: generic fn @CallFacet(%T.loc21_14.1: %Interface.type) {
|
||||
// CHECK:STDOUT: %T.loc21_14.2: %Interface.type = bind_symbolic_name T, 0 [symbolic = %T.loc21_14.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %T.patt.loc21_14.2: %Interface.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc21_14.2 (constants.%T.patt)]
|
||||
// CHECK:STDOUT: %.loc21_32.3: type = facet_access_type %T.loc21_14.2 [symbolic = %.loc21_32.3 (constants.%.3)]
|
||||
// CHECK:STDOUT: %.loc21_32.3: type = facet_access_type %T.loc21_14.2 [symbolic = %.loc21_32.3 (constants.%.4)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%T.param_patt: %Interface.type, %x.param_patt: @CallFacet.%.loc21_32.3 (%.3)) {
|
||||
// CHECK:STDOUT: fn(%T.param_patt: %Interface.type, %x.param_patt: @CallFacet.%.loc21_32.3 (%.4)) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %x.ref: @CallFacet.%.loc21_32.3 (%.3) = name_ref x, %x
|
||||
// CHECK:STDOUT: %x.ref: @CallFacet.%.loc21_32.3 (%.4) = name_ref x, %x
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
@@ -129,6 +133,6 @@ fn CallFacet(T:! Interface, x: T) {
|
||||
// CHECK:STDOUT: specific @CallFacet(constants.%T) {
|
||||
// CHECK:STDOUT: %T.loc21_14.2 => constants.%T
|
||||
// CHECK:STDOUT: %T.patt.loc21_14.2 => constants.%T
|
||||
// CHECK:STDOUT: %.loc21_32.3 => constants.%.3
|
||||
// CHECK:STDOUT: %.loc21_32.3 => constants.%.4
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
+59
-60
@@ -25,7 +25,7 @@ fn Impls(V:! J where .Self impls I);
|
||||
|
||||
fn And(W:! I where .Self impls J and .Member == ());
|
||||
|
||||
// --- fail_todo_equal_constraint.carbon
|
||||
// --- equal_constraint.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
@@ -33,13 +33,6 @@ interface N {
|
||||
let P:! type;
|
||||
}
|
||||
|
||||
// CHECK:STDERR: fail_todo_equal_constraint.carbon:[[@LINE+7]]:27: error: cannot implicitly convert from `{}` to `<associated type in N>` [ImplicitAsConversionFailure]
|
||||
// CHECK:STDERR: fn Equal(T:! N where .P = {});
|
||||
// CHECK:STDERR: ^~
|
||||
// CHECK:STDERR: fail_todo_equal_constraint.carbon:[[@LINE+4]]:27: note: type `{}` does not implement interface `ImplicitAs(<associated type in N>)` [MissingImplInMemberAccessNote]
|
||||
// CHECK:STDERR: fn Equal(T:! N where .P = {});
|
||||
// CHECK:STDERR: ^~
|
||||
// CHECK:STDERR:
|
||||
fn Equal(T:! N where .P = {});
|
||||
|
||||
// --- fail_todo_associated_type_impls.carbon
|
||||
@@ -53,10 +46,7 @@ interface K {
|
||||
let Associated:! L;
|
||||
}
|
||||
|
||||
// CHECK:STDERR: fail_todo_associated_type_impls.carbon:[[@LINE+7]]:36: error: cannot implicitly convert from `<associated L in K>` to `type` [ImplicitAsConversionFailure]
|
||||
// CHECK:STDERR: fn AssociatedTypeImpls(W:! K where .Associated impls M);
|
||||
// CHECK:STDERR: ^~~~~~~~~~~
|
||||
// CHECK:STDERR: fail_todo_associated_type_impls.carbon:[[@LINE+4]]:36: note: type `<associated L in K>` does not implement interface `ImplicitAs(type)` [MissingImplInMemberAccessNote]
|
||||
// CHECK:STDERR: fail_todo_associated_type_impls.carbon:[[@LINE+4]]:36: error: cannot evaluate type expression [TypeExprEvaluationFailure]
|
||||
// CHECK:STDERR: fn AssociatedTypeImpls(W:! K where .Associated impls M);
|
||||
// CHECK:STDERR: ^~~~~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
@@ -69,12 +59,10 @@ library "[[@TEST_NAME]]";
|
||||
import library "state_constraints";
|
||||
|
||||
// `2` can't be converted to the type of `I.Member`
|
||||
// TODO: The diagnostics are wrong since member access into facets isn't
|
||||
// working properly yet.
|
||||
// CHECK:STDERR: fail_check_rewrite_constraints.carbon:[[@LINE+7]]:46: error: cannot implicitly convert from `Core.IntLiteral` to `<associated type in I>` [ImplicitAsConversionFailure]
|
||||
// CHECK:STDERR: fail_check_rewrite_constraints.carbon:[[@LINE+7]]:46: error: cannot implicitly convert from `Core.IntLiteral` to `type` [ImplicitAsConversionFailure]
|
||||
// CHECK:STDERR: fn RewriteTypeMismatch(X:! I where .Member = 2);
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR: fail_check_rewrite_constraints.carbon:[[@LINE+4]]:46: note: type `Core.IntLiteral` does not implement interface `ImplicitAs(<associated type in I>)` [MissingImplInMemberAccessNote]
|
||||
// CHECK:STDERR: fail_check_rewrite_constraints.carbon:[[@LINE+4]]:46: note: type `Core.IntLiteral` does not implement interface `ImplicitAs(type)` [MissingImplInMemberAccessNote]
|
||||
// CHECK:STDERR: fn RewriteTypeMismatch(X:! I where .Member = 2);
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR:
|
||||
@@ -201,6 +189,7 @@ let B: type where .Self impls A = D;
|
||||
// CHECK:STDOUT: %Impls.type: type = fn_type @Impls [template]
|
||||
// CHECK:STDOUT: %Impls: %Impls.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.6: type = facet_access_type %.Self.1 [symbolic]
|
||||
// CHECK:STDOUT: %.7: <witness> = facet_access_witness %.Self.1 [symbolic]
|
||||
// CHECK:STDOUT: %I.type.3: type = facet_type <@I where TODO> [template]
|
||||
// CHECK:STDOUT: %W: %I.type.3 = bind_symbolic_name W, 0 [symbolic]
|
||||
// CHECK:STDOUT: %W.patt: %I.type.3 = symbolic_binding_pattern W, 0 [symbolic]
|
||||
@@ -269,10 +258,12 @@ let B: type where .Self impls A = D;
|
||||
// CHECK:STDOUT: %.loc15_20.2: type = converted %.Self.ref.loc15_20, %.loc15_20.1 [symbolic = constants.%.6]
|
||||
// CHECK:STDOUT: %.Self.ref.loc15_38: %I.type.1 = name_ref .Self, %.Self [symbolic = constants.%.Self.1]
|
||||
// CHECK:STDOUT: %Member.ref: %.1 = name_ref Member, @I.%.loc7 [template = constants.%.2]
|
||||
// CHECK:STDOUT: %.loc15_38.1: <witness> = facet_access_witness %.Self.ref.loc15_38 [symbolic = constants.%.7]
|
||||
// CHECK:STDOUT: %.loc15_38.2: type = interface_witness_access %.loc15_38.1, element0
|
||||
// CHECK:STDOUT: %.loc15_50: %empty_tuple.type = tuple_literal ()
|
||||
// CHECK:STDOUT: %.loc15_14: type = where_expr %.Self [template = constants.%I.type.3] {
|
||||
// CHECK:STDOUT: requirement_impls %.loc15_20.2, %J.ref
|
||||
// CHECK:STDOUT: requirement_equivalent %Member.ref, %.loc15_50
|
||||
// CHECK:STDOUT: requirement_equivalent %.loc15_38.2, %.loc15_50
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %W.param: %I.type.3 = value_param runtime_param<invalid>
|
||||
// CHECK:STDOUT: %W.loc15_8.1: %I.type.3 = bind_symbolic_name W, 0, %W.param [symbolic = %W.loc15_8.2 (constants.%W)]
|
||||
@@ -338,15 +329,16 @@ let B: type where .Self impls A = D;
|
||||
// CHECK:STDOUT: %W.patt.loc15_8.2 => constants.%W
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_equal_constraint.carbon
|
||||
// CHECK:STDOUT: --- equal_constraint.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %N.type.1: type = facet_type <@N> [template]
|
||||
// CHECK:STDOUT: %Self.1: %N.type.1 = bind_symbolic_name Self, 0 [symbolic]
|
||||
// CHECK:STDOUT: %Self: %N.type.1 = bind_symbolic_name Self, 0 [symbolic]
|
||||
// CHECK:STDOUT: %.1: type = assoc_entity_type %N.type.1, type [template]
|
||||
// CHECK:STDOUT: %.2: %.1 = assoc_entity element0, @N.%P [template]
|
||||
// CHECK:STDOUT: %.Self: %N.type.1 = bind_symbolic_name .Self, 0 [symbolic]
|
||||
// CHECK:STDOUT: %.3: type = struct_type {} [template]
|
||||
// CHECK:STDOUT: %.3: <witness> = facet_access_witness %.Self [symbolic]
|
||||
// CHECK:STDOUT: %.4: type = struct_type {} [template]
|
||||
// CHECK:STDOUT: %N.type.2: type = facet_type <@N where TODO> [template]
|
||||
// CHECK:STDOUT: %T: %N.type.2 = bind_symbolic_name T, 0 [symbolic]
|
||||
// CHECK:STDOUT: %T.patt: %N.type.2 = symbolic_binding_pattern T, 0 [symbolic]
|
||||
@@ -356,7 +348,6 @@ let B: type where .Self impls A = D;
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [template] {
|
||||
// CHECK:STDOUT: .ImplicitAs = %import_ref.1
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/...
|
||||
// CHECK:STDOUT: }
|
||||
@@ -371,25 +362,27 @@ let B: type where .Self impls A = D;
|
||||
// CHECK:STDOUT: %Core.import = import Core
|
||||
// CHECK:STDOUT: %N.decl: type = interface_decl @N [template = constants.%N.type.1] {} {}
|
||||
// CHECK:STDOUT: %Equal.decl: %Equal.type = fn_decl @Equal [template = constants.%Equal] {
|
||||
// CHECK:STDOUT: %T.patt.loc15_10.1: %N.type.2 = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc15_10.2 (constants.%T.patt)]
|
||||
// CHECK:STDOUT: %T.param_patt: %N.type.2 = value_param_pattern %T.patt.loc15_10.1, runtime_param<invalid> [symbolic = %T.patt.loc15_10.2 (constants.%T.patt)]
|
||||
// CHECK:STDOUT: %T.patt.loc8_10.1: %N.type.2 = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc8_10.2 (constants.%T.patt)]
|
||||
// CHECK:STDOUT: %T.param_patt: %N.type.2 = value_param_pattern %T.patt.loc8_10.1, runtime_param<invalid> [symbolic = %T.patt.loc8_10.2 (constants.%T.patt)]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %N.ref: type = name_ref N, file.%N.decl [template = constants.%N.type.1]
|
||||
// CHECK:STDOUT: %.Self: %N.type.1 = bind_symbolic_name .Self, 0 [symbolic = constants.%.Self]
|
||||
// CHECK:STDOUT: %.Self.ref: %N.type.1 = name_ref .Self, %.Self [symbolic = constants.%.Self]
|
||||
// CHECK:STDOUT: %P.ref: %.1 = name_ref P, @N.%.loc5 [template = constants.%.2]
|
||||
// CHECK:STDOUT: %.loc15_28.1: %.3 = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc15_28.2: %.1 = converted %.loc15_28.1, <error> [template = <error>]
|
||||
// CHECK:STDOUT: %.loc15_16: type = where_expr %.Self [template = constants.%N.type.2] {
|
||||
// CHECK:STDOUT: requirement_rewrite %P.ref, <error>
|
||||
// CHECK:STDOUT: %.loc8_22.1: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.3]
|
||||
// CHECK:STDOUT: %.loc8_22.2: type = interface_witness_access %.loc8_22.1, element0
|
||||
// CHECK:STDOUT: %.loc8_28.1: %.4 = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc8_28.2: type = converted %.loc8_28.1, constants.%.4 [template = constants.%.4]
|
||||
// CHECK:STDOUT: %.loc8_16: type = where_expr %.Self [template = constants.%N.type.2] {
|
||||
// CHECK:STDOUT: requirement_rewrite %.loc8_22.2, %.loc8_28.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %T.param: %N.type.2 = value_param runtime_param<invalid>
|
||||
// CHECK:STDOUT: %T.loc15_10.1: %N.type.2 = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc15_10.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %T.loc8_10.1: %N.type.2 = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc8_10.2 (constants.%T)]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: interface @N {
|
||||
// CHECK:STDOUT: %Self: %N.type.1 = bind_symbolic_name Self, 0 [symbolic = constants.%Self.1]
|
||||
// CHECK:STDOUT: %Self: %N.type.1 = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
|
||||
// CHECK:STDOUT: %P: type = assoc_const_decl P [template]
|
||||
// CHECK:STDOUT: %.loc5: %.1 = assoc_entity element0, %P [template = constants.%.2]
|
||||
// CHECK:STDOUT:
|
||||
@@ -399,16 +392,16 @@ let B: type where .Self impls A = D;
|
||||
// CHECK:STDOUT: witness = (%P)
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic fn @Equal(%T.loc15_10.1: %N.type.2) {
|
||||
// CHECK:STDOUT: %T.loc15_10.2: %N.type.2 = bind_symbolic_name T, 0 [symbolic = %T.loc15_10.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %T.patt.loc15_10.2: %N.type.2 = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc15_10.2 (constants.%T.patt)]
|
||||
// CHECK:STDOUT: generic fn @Equal(%T.loc8_10.1: %N.type.2) {
|
||||
// CHECK:STDOUT: %T.loc8_10.2: %N.type.2 = bind_symbolic_name T, 0 [symbolic = %T.loc8_10.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %T.patt.loc8_10.2: %N.type.2 = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc8_10.2 (constants.%T.patt)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%T.param_patt: %N.type.2);
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Equal(constants.%T) {
|
||||
// CHECK:STDOUT: %T.loc15_10.2 => constants.%T
|
||||
// CHECK:STDOUT: %T.patt.loc15_10.2 => constants.%T
|
||||
// CHECK:STDOUT: %T.loc8_10.2 => constants.%T
|
||||
// CHECK:STDOUT: %T.patt.loc8_10.2 => constants.%T
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_associated_type_impls.carbon
|
||||
@@ -423,6 +416,7 @@ let B: type where .Self impls A = D;
|
||||
// CHECK:STDOUT: %.1: type = assoc_entity_type %K.type.1, %L.type [template]
|
||||
// CHECK:STDOUT: %.2: %.1 = assoc_entity element0, @K.%Associated [template]
|
||||
// CHECK:STDOUT: %.Self: %K.type.1 = bind_symbolic_name .Self, 0 [symbolic]
|
||||
// CHECK:STDOUT: %.3: <witness> = facet_access_witness %.Self [symbolic]
|
||||
// CHECK:STDOUT: %K.type.2: type = facet_type <@K where TODO> [template]
|
||||
// CHECK:STDOUT: %W: %K.type.2 = bind_symbolic_name W, 0 [symbolic]
|
||||
// CHECK:STDOUT: %W.patt: %K.type.2 = symbolic_binding_pattern W, 0 [symbolic]
|
||||
@@ -432,7 +426,6 @@ let B: type where .Self impls A = D;
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [template] {
|
||||
// CHECK:STDOUT: .ImplicitAs = %import_ref.1
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/...
|
||||
// CHECK:STDOUT: }
|
||||
@@ -451,20 +444,23 @@ let B: type where .Self impls A = D;
|
||||
// CHECK:STDOUT: %M.decl: type = interface_decl @M [template = constants.%M.type] {} {}
|
||||
// CHECK:STDOUT: %K.decl: type = interface_decl @K [template = constants.%K.type.1] {} {}
|
||||
// CHECK:STDOUT: %AssociatedTypeImpls.decl: %AssociatedTypeImpls.type = fn_decl @AssociatedTypeImpls [template = constants.%AssociatedTypeImpls] {
|
||||
// CHECK:STDOUT: %W.patt.loc18_24.1: %K.type.2 = symbolic_binding_pattern W, 0 [symbolic = %W.patt.loc18_24.2 (constants.%W.patt)]
|
||||
// CHECK:STDOUT: %W.param_patt: %K.type.2 = value_param_pattern %W.patt.loc18_24.1, runtime_param<invalid> [symbolic = %W.patt.loc18_24.2 (constants.%W.patt)]
|
||||
// CHECK:STDOUT: %W.patt.loc15_24.1: %K.type.2 = symbolic_binding_pattern W, 0 [symbolic = %W.patt.loc15_24.2 (constants.%W.patt)]
|
||||
// CHECK:STDOUT: %W.param_patt: %K.type.2 = value_param_pattern %W.patt.loc15_24.1, runtime_param<invalid> [symbolic = %W.patt.loc15_24.2 (constants.%W.patt)]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %K.ref: type = name_ref K, file.%K.decl [template = constants.%K.type.1]
|
||||
// CHECK:STDOUT: %.Self: %K.type.1 = bind_symbolic_name .Self, 0 [symbolic = constants.%.Self]
|
||||
// CHECK:STDOUT: %.Self.ref: %K.type.1 = name_ref .Self, %.Self [symbolic = constants.%.Self]
|
||||
// CHECK:STDOUT: %Associated.ref: %.1 = name_ref Associated, @K.%.loc8 [template = constants.%.2]
|
||||
// CHECK:STDOUT: %.loc15_36.1: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.3]
|
||||
// CHECK:STDOUT: %.loc15_36.2: %L.type = interface_witness_access %.loc15_36.1, element0
|
||||
// CHECK:STDOUT: %M.ref: type = name_ref M, file.%M.decl [template = constants.%M.type]
|
||||
// CHECK:STDOUT: %.loc18_36: type = converted %Associated.ref, <error> [template = <error>]
|
||||
// CHECK:STDOUT: %.loc18_30: type = where_expr %.Self [template = constants.%K.type.2] {
|
||||
// CHECK:STDOUT: %.loc15_36.3: type = facet_access_type %.loc15_36.2
|
||||
// CHECK:STDOUT: %.loc15_36.4: type = converted %.loc15_36.2, %.loc15_36.3
|
||||
// CHECK:STDOUT: %.loc15_30: type = where_expr %.Self [template = constants.%K.type.2] {
|
||||
// CHECK:STDOUT: requirement_impls <error>, %M.ref
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %W.param: %K.type.2 = value_param runtime_param<invalid>
|
||||
// CHECK:STDOUT: %W.loc18_24.1: %K.type.2 = bind_symbolic_name W, 0, %W.param [symbolic = %W.loc18_24.2 (constants.%W)]
|
||||
// CHECK:STDOUT: %W.loc15_24.1: %K.type.2 = bind_symbolic_name W, 0, %W.param [symbolic = %W.loc15_24.2 (constants.%W)]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -496,16 +492,16 @@ let B: type where .Self impls A = D;
|
||||
// CHECK:STDOUT: witness = (%Associated)
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic fn @AssociatedTypeImpls(%W.loc18_24.1: %K.type.2) {
|
||||
// CHECK:STDOUT: %W.loc18_24.2: %K.type.2 = bind_symbolic_name W, 0 [symbolic = %W.loc18_24.2 (constants.%W)]
|
||||
// CHECK:STDOUT: %W.patt.loc18_24.2: %K.type.2 = symbolic_binding_pattern W, 0 [symbolic = %W.patt.loc18_24.2 (constants.%W.patt)]
|
||||
// CHECK:STDOUT: generic fn @AssociatedTypeImpls(%W.loc15_24.1: %K.type.2) {
|
||||
// CHECK:STDOUT: %W.loc15_24.2: %K.type.2 = bind_symbolic_name W, 0 [symbolic = %W.loc15_24.2 (constants.%W)]
|
||||
// CHECK:STDOUT: %W.patt.loc15_24.2: %K.type.2 = symbolic_binding_pattern W, 0 [symbolic = %W.patt.loc15_24.2 (constants.%W.patt)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%W.param_patt: %K.type.2);
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @AssociatedTypeImpls(constants.%W) {
|
||||
// CHECK:STDOUT: %W.loc18_24.2 => constants.%W
|
||||
// CHECK:STDOUT: %W.patt.loc18_24.2 => constants.%W
|
||||
// CHECK:STDOUT: %W.loc15_24.2 => constants.%W
|
||||
// CHECK:STDOUT: %W.patt.loc15_24.2 => constants.%W
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_check_rewrite_constraints.carbon
|
||||
@@ -515,7 +511,8 @@ let B: type where .Self impls A = D;
|
||||
// CHECK:STDOUT: %.Self: %I.type.1 = bind_symbolic_name .Self, 0 [symbolic]
|
||||
// CHECK:STDOUT: %.1: type = assoc_entity_type %I.type.1, type [template]
|
||||
// CHECK:STDOUT: %.2: %.1 = assoc_entity element0, imports.%import_ref.11 [template]
|
||||
// CHECK:STDOUT: %.3: Core.IntLiteral = int_value 2 [template]
|
||||
// CHECK:STDOUT: %.3: <witness> = facet_access_witness %.Self [symbolic]
|
||||
// CHECK:STDOUT: %.4: Core.IntLiteral = int_value 2 [template]
|
||||
// CHECK:STDOUT: %I.type.2: type = facet_type <@I where TODO> [template]
|
||||
// CHECK:STDOUT: %X: %I.type.2 = bind_symbolic_name X, 0 [symbolic]
|
||||
// CHECK:STDOUT: %X.patt: %I.type.2 = symbolic_binding_pattern X, 0 [symbolic]
|
||||
@@ -528,7 +525,7 @@ let B: type where .Self impls A = D;
|
||||
// CHECK:STDOUT: %import_ref.2: type = import_ref Main//state_constraints, inst+7, loaded [template = constants.%I.type.1]
|
||||
// CHECK:STDOUT: %import_ref.3 = import_ref Main//state_constraints, inst+35, unloaded
|
||||
// CHECK:STDOUT: %import_ref.4 = import_ref Main//state_constraints, inst+57, unloaded
|
||||
// CHECK:STDOUT: %import_ref.5 = import_ref Main//state_constraints, inst+82, unloaded
|
||||
// CHECK:STDOUT: %import_ref.5 = import_ref Main//state_constraints, inst+85, unloaded
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [template] {
|
||||
// CHECK:STDOUT: .ImplicitAs = %import_ref.12
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
@@ -554,20 +551,22 @@ let B: type where .Self impls A = D;
|
||||
// CHECK:STDOUT: %Core.import = import Core
|
||||
// CHECK:STDOUT: %default.import = import <invalid>
|
||||
// CHECK:STDOUT: %RewriteTypeMismatch.decl: %RewriteTypeMismatch.type = fn_decl @RewriteTypeMismatch [template = constants.%RewriteTypeMismatch] {
|
||||
// CHECK:STDOUT: %X.patt.loc16_24.1: %I.type.2 = symbolic_binding_pattern X, 0 [symbolic = %X.patt.loc16_24.2 (constants.%X.patt)]
|
||||
// CHECK:STDOUT: %X.param_patt: %I.type.2 = value_param_pattern %X.patt.loc16_24.1, runtime_param<invalid> [symbolic = %X.patt.loc16_24.2 (constants.%X.patt)]
|
||||
// CHECK:STDOUT: %X.patt.loc14_24.1: %I.type.2 = symbolic_binding_pattern X, 0 [symbolic = %X.patt.loc14_24.2 (constants.%X.patt)]
|
||||
// CHECK:STDOUT: %X.param_patt: %I.type.2 = value_param_pattern %X.patt.loc14_24.1, runtime_param<invalid> [symbolic = %X.patt.loc14_24.2 (constants.%X.patt)]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %I.ref: type = name_ref I, imports.%import_ref.2 [template = constants.%I.type.1]
|
||||
// CHECK:STDOUT: %.Self: %I.type.1 = bind_symbolic_name .Self, 0 [symbolic = constants.%.Self]
|
||||
// CHECK:STDOUT: %.Self.ref: %I.type.1 = name_ref .Self, %.Self [symbolic = constants.%.Self]
|
||||
// CHECK:STDOUT: %Member.ref: %.1 = name_ref Member, imports.%import_ref.7 [template = constants.%.2]
|
||||
// CHECK:STDOUT: %.loc16_46.1: Core.IntLiteral = int_value 2 [template = constants.%.3]
|
||||
// CHECK:STDOUT: %.loc16_46.2: %.1 = converted %.loc16_46.1, <error> [template = <error>]
|
||||
// CHECK:STDOUT: %.loc16_30: type = where_expr %.Self [template = constants.%I.type.2] {
|
||||
// CHECK:STDOUT: requirement_rewrite %Member.ref, <error>
|
||||
// CHECK:STDOUT: %.loc14_36.1: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.3]
|
||||
// CHECK:STDOUT: %.loc14_36.2: type = interface_witness_access %.loc14_36.1, element0
|
||||
// CHECK:STDOUT: %.loc14_46.1: Core.IntLiteral = int_value 2 [template = constants.%.4]
|
||||
// CHECK:STDOUT: %.loc14_46.2: type = converted %.loc14_46.1, <error> [template = <error>]
|
||||
// CHECK:STDOUT: %.loc14_30: type = where_expr %.Self [template = constants.%I.type.2] {
|
||||
// CHECK:STDOUT: requirement_rewrite %.loc14_36.2, <error>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %X.param: %I.type.2 = value_param runtime_param<invalid>
|
||||
// CHECK:STDOUT: %X.loc16_24.1: %I.type.2 = bind_symbolic_name X, 0, %X.param [symbolic = %X.loc16_24.2 (constants.%X)]
|
||||
// CHECK:STDOUT: %X.loc14_24.1: %I.type.2 = bind_symbolic_name X, 0, %X.param [symbolic = %X.loc14_24.2 (constants.%X)]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -579,16 +578,16 @@ let B: type where .Self impls A = D;
|
||||
// CHECK:STDOUT: witness = (imports.%import_ref.9, imports.%import_ref.10)
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic fn @RewriteTypeMismatch(%X.loc16_24.1: %I.type.2) {
|
||||
// CHECK:STDOUT: %X.loc16_24.2: %I.type.2 = bind_symbolic_name X, 0 [symbolic = %X.loc16_24.2 (constants.%X)]
|
||||
// CHECK:STDOUT: %X.patt.loc16_24.2: %I.type.2 = symbolic_binding_pattern X, 0 [symbolic = %X.patt.loc16_24.2 (constants.%X.patt)]
|
||||
// CHECK:STDOUT: generic fn @RewriteTypeMismatch(%X.loc14_24.1: %I.type.2) {
|
||||
// CHECK:STDOUT: %X.loc14_24.2: %I.type.2 = bind_symbolic_name X, 0 [symbolic = %X.loc14_24.2 (constants.%X)]
|
||||
// CHECK:STDOUT: %X.patt.loc14_24.2: %I.type.2 = symbolic_binding_pattern X, 0 [symbolic = %X.patt.loc14_24.2 (constants.%X.patt)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%X.param_patt: %I.type.2);
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @RewriteTypeMismatch(constants.%X) {
|
||||
// CHECK:STDOUT: %X.loc16_24.2 => constants.%X
|
||||
// CHECK:STDOUT: %X.patt.loc16_24.2 => constants.%X
|
||||
// CHECK:STDOUT: %X.loc14_24.2 => constants.%X
|
||||
// CHECK:STDOUT: %X.patt.loc14_24.2 => constants.%X
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_left_of_impls_non_type.carbon
|
||||
@@ -786,7 +785,7 @@ let B: type where .Self impls A = D;
|
||||
// CHECK:STDOUT: %import_ref.2 = import_ref Main//state_constraints, inst+7, unloaded
|
||||
// CHECK:STDOUT: %import_ref.3 = import_ref Main//state_constraints, inst+35, unloaded
|
||||
// CHECK:STDOUT: %import_ref.4: %Impls.type = import_ref Main//state_constraints, inst+57, loaded [template = constants.%Impls]
|
||||
// CHECK:STDOUT: %import_ref.5 = import_ref Main//state_constraints, inst+82, unloaded
|
||||
// CHECK:STDOUT: %import_ref.5 = import_ref Main//state_constraints, inst+85, unloaded
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [template] {
|
||||
// CHECK:STDOUT: .ImplicitAs = %import_ref.7
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
|
||||
+4
-1
@@ -100,6 +100,7 @@ class D {
|
||||
// CHECK:STDOUT: %T.patt: %I.type.2 = symbolic_binding_pattern T, 0 [symbolic]
|
||||
// CHECK:STDOUT: %PeriodSelf.type: type = fn_type @PeriodSelf [template]
|
||||
// CHECK:STDOUT: %PeriodSelf: %PeriodSelf.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.3: <witness> = facet_access_witness %.Self.1 [symbolic]
|
||||
// CHECK:STDOUT: %I.type.3: type = facet_type <@I where TODO> [template]
|
||||
// CHECK:STDOUT: %U: %I.type.3 = bind_symbolic_name U, 0 [symbolic]
|
||||
// CHECK:STDOUT: %U.patt: %I.type.3 = symbolic_binding_pattern U, 0 [symbolic]
|
||||
@@ -152,9 +153,11 @@ class D {
|
||||
// CHECK:STDOUT: %.Self: %I.type.1 = bind_symbolic_name .Self, 0 [symbolic = constants.%.Self.1]
|
||||
// CHECK:STDOUT: %.Self.ref: %I.type.1 = name_ref .Self, %.Self [symbolic = constants.%.Self.1]
|
||||
// CHECK:STDOUT: %Member.ref: %.1 = name_ref Member, @I.%.loc5 [template = constants.%.2]
|
||||
// CHECK:STDOUT: %.loc10_29.1: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.3]
|
||||
// CHECK:STDOUT: %.loc10_29.2: type = interface_witness_access %.loc10_29.1, element0
|
||||
// CHECK:STDOUT: %.loc10_41: %empty_tuple.type = tuple_literal ()
|
||||
// CHECK:STDOUT: %.loc10_23: type = where_expr %.Self [template = constants.%I.type.3] {
|
||||
// CHECK:STDOUT: requirement_equivalent %Member.ref, %.loc10_41
|
||||
// CHECK:STDOUT: requirement_equivalent %.loc10_29.2, %.loc10_41
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %U.param: %I.type.3 = value_param runtime_param<invalid>
|
||||
// CHECK:STDOUT: %U.loc10_17.1: %I.type.3 = bind_symbolic_name U, 0, %U.param [symbolic = %U.loc10_17.2 (constants.%U)]
|
||||
|
||||
+7
-4
@@ -21,10 +21,11 @@ fn NotGenericF(U: I where .T == i32) {}
|
||||
// CHECK:STDOUT: %.1: type = assoc_entity_type %I.type.1, type [template]
|
||||
// CHECK:STDOUT: %.2: %.1 = assoc_entity element0, @I.%T [template]
|
||||
// CHECK:STDOUT: %.Self: %I.type.1 = bind_symbolic_name .Self, 0 [symbolic]
|
||||
// CHECK:STDOUT: %.3: Core.IntLiteral = int_value 32 [template]
|
||||
// CHECK:STDOUT: %.3: <witness> = facet_access_witness %.Self [symbolic]
|
||||
// CHECK:STDOUT: %.4: Core.IntLiteral = int_value 32 [template]
|
||||
// CHECK:STDOUT: %Int.type: type = fn_type @Int [template]
|
||||
// CHECK:STDOUT: %Int: %Int.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %i32: type = int_type signed, %.3 [template]
|
||||
// CHECK:STDOUT: %i32: type = int_type signed, %.4 [template]
|
||||
// CHECK:STDOUT: %I.type.2: type = facet_type <@I where TODO> [template]
|
||||
// CHECK:STDOUT: %NotGenericF.type: type = fn_type @NotGenericF [template]
|
||||
// CHECK:STDOUT: %NotGenericF: %NotGenericF.type = struct_value () [template]
|
||||
@@ -54,10 +55,12 @@ fn NotGenericF(U: I where .T == i32) {}
|
||||
// CHECK:STDOUT: %.Self: %I.type.1 = bind_symbolic_name .Self, 0 [symbolic = constants.%.Self]
|
||||
// CHECK:STDOUT: %.Self.ref: %I.type.1 = name_ref .Self, %.Self [symbolic = constants.%.Self]
|
||||
// CHECK:STDOUT: %T.ref: %.1 = name_ref T, @I.%.loc11 [template = constants.%.2]
|
||||
// CHECK:STDOUT: %.loc14_33: Core.IntLiteral = int_value 32 [template = constants.%.3]
|
||||
// CHECK:STDOUT: %.loc14_27.1: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.3]
|
||||
// CHECK:STDOUT: %.loc14_27.2: type = interface_witness_access %.loc14_27.1, element0
|
||||
// CHECK:STDOUT: %.loc14_33: Core.IntLiteral = int_value 32 [template = constants.%.4]
|
||||
// CHECK:STDOUT: %int.make_type_signed: init type = call constants.%Int(%.loc14_33) [template = constants.%i32]
|
||||
// CHECK:STDOUT: %.loc14_21: type = where_expr %.Self [template = constants.%I.type.2] {
|
||||
// CHECK:STDOUT: requirement_equivalent %T.ref, %int.make_type_signed
|
||||
// CHECK:STDOUT: requirement_equivalent %.loc14_27.2, %int.make_type_signed
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %U.param: %I.type.2 = value_param runtime_param0
|
||||
// CHECK:STDOUT: %U: %I.type.2 = bind_name U, %U.param
|
||||
|
||||
@@ -264,6 +264,7 @@ auto GetExprCategory(const File& file, InstId inst_id) -> ExprCategory {
|
||||
case CompleteTypeWitness::Kind:
|
||||
case ConstType::Kind:
|
||||
case FacetAccessType::Kind:
|
||||
case FacetAccessWitness::Kind:
|
||||
case FacetType::Kind:
|
||||
case FacetValue::Kind:
|
||||
case FloatLiteral::Kind:
|
||||
|
||||
@@ -85,6 +85,7 @@ CARBON_SEM_IR_INST_KIND(ConstType)
|
||||
CARBON_SEM_IR_INST_KIND(Converted)
|
||||
CARBON_SEM_IR_INST_KIND(Deref)
|
||||
CARBON_SEM_IR_INST_KIND(FacetAccessType)
|
||||
CARBON_SEM_IR_INST_KIND(FacetAccessWitness)
|
||||
CARBON_SEM_IR_INST_KIND(FacetType)
|
||||
CARBON_SEM_IR_INST_KIND(FacetValue)
|
||||
CARBON_SEM_IR_INST_KIND(FieldDecl)
|
||||
|
||||
@@ -192,6 +192,12 @@ auto StringifyTypeExpr(const SemIR::File& outer_sem_ir, InstId outer_inst_id)
|
||||
push_inst_id(inst.facet_value_inst_id);
|
||||
break;
|
||||
}
|
||||
case CARBON_KIND(FacetAccessWitness inst): {
|
||||
out << "<witness for ";
|
||||
push_string(">");
|
||||
push_inst_id(inst.facet_value_inst_id);
|
||||
break;
|
||||
}
|
||||
case CARBON_KIND(FacetType inst): {
|
||||
const FacetTypeInfo& facet_type_info =
|
||||
sem_ir.facet_types().Get(inst.facet_type_id);
|
||||
|
||||
@@ -602,7 +602,21 @@ struct FacetAccessType {
|
||||
InstId facet_value_inst_id;
|
||||
};
|
||||
|
||||
// TODO: `FacetAccessWitness`
|
||||
// Represents accessing the `witness` field in a facet value, which is
|
||||
// notionally a pair of a type and a witness.
|
||||
struct FacetAccessWitness {
|
||||
static constexpr auto Kind =
|
||||
InstKind::FacetAccessWitness.Define<Parse::NodeId>(
|
||||
{.ir_name = "facet_access_witness",
|
||||
.is_type = InstIsType::Never,
|
||||
.constant_kind = InstConstantKind::SymbolicOnly,
|
||||
.is_lowered = false});
|
||||
|
||||
// Always the builtin witness type.
|
||||
TypeId type_id;
|
||||
// An instruction that evaluates to a `FacetValue`.
|
||||
InstId facet_value_inst_id;
|
||||
};
|
||||
|
||||
// A facet type value.
|
||||
struct FacetType {
|
||||
|
||||
Reference in New Issue
Block a user