Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use FacetAccessType when converting to a value of type FacetType #4925

Merged
merged 3 commits into from
Feb 12, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions toolchain/check/convert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -991,7 +991,24 @@ static auto PerformBuiltinConversion(Context& context, SemIR::LocId loc_id,
}

if (sem_ir.types().Is<SemIR::FacetType>(target.type_id)) {
if (sem_ir.types().Is<SemIR::FacetType>(value_type_id)) {
auto lookup_inst = value_id;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'd usually call this lookup_inst_id instead to indicate that it's an InstId not an Inst.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, done. Thanks for the review!


// `FacetAccessType` wraps an instruction that evaluates to a facet value
// (of type `FacetType`). If the `FacetType` matches the target
// `FacetType` then we don't need to do impl lookup. Otherwise, we want to
// try convert the result of the instruction in the `FacetAccessType`.
if (auto facet_access_type_value =
context.insts().TryGetAs<SemIR::FacetAccessType>(lookup_inst)) {
auto facet_value_inst_id = facet_access_type_value->facet_value_inst_id;
if (context.insts().Get(facet_value_inst_id).type_id() ==
target.type_id) {
return facet_value_inst_id;
}
lookup_inst = facet_access_type_value->facet_value_inst_id;
}

if (sem_ir.types().Is<SemIR::FacetType>(
sem_ir.insts().Get(lookup_inst).type_id())) {
// Conversion from a facet value (which has type `FacetType`) to a
// different facet value (which has type `FacetType`), if the value's
// `FacetType` satisfies the requirements of the target `FacetType`. The
Expand All @@ -1004,23 +1021,28 @@ static auto PerformBuiltinConversion(Context& context, SemIR::LocId loc_id,
// so using that here would be like an implicit cast back to the concrete
// type.
context.TODO(loc_id, "Facet value converting to facet value");
} else if (sem_ir.types().Is<SemIR::TypeType>(value_type_id)) {
return value_id;
}

if (sem_ir.types().Is<SemIR::TypeType>(
sem_ir.insts().Get(lookup_inst).type_id())) {
// Conversion from a type value (which has type `type`) to a facet value
// (which has type `FacetType`), if the type satisfies the requirements of
// the target `FacetType`, as determined by finding an impl witness. This
// binds the value to the `FacetType` with a `FacetValue`.

auto witness_inst_id = LookupImplWitness(
context, loc_id,
// The value instruction evaluates to a type value (which has type
// `type`). This gets that type value if it's available at compile
// time, as a constant value.
context.constant_values().Get(value_id),
context.constant_values().Get(lookup_inst),
context.types().GetConstantId(target.type_id));
if (witness_inst_id != SemIR::InstId::None) {
return context.AddInst<SemIR::FacetValue>(
loc_id, {
.type_id = target.type_id,
.type_inst_id = value_id,
.type_inst_id = lookup_inst,
.witness_inst_id = witness_inst_id,
});
}
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.