Skip to content
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
25 changes: 20 additions & 5 deletions toolchain/check/convert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1211,11 +1211,26 @@ static auto PerformBuiltinConversion(

if (auto facet_access_type_inst =
sem_ir.insts().TryGetAs<SemIR::FacetAccessType>(const_value_id)) {
// Conversion from a `FacetAccessType` to a `FacetValue` of the target
// `FacetType` if the instruction in the `FacetAccessType` is of a
// `FacetType` that satisfies the requirements of the target `FacetType`.
// If the `FacetType` exactly matches the target `FacetType` then we can
// shortcut and use that value, and avoid impl lookup.
// Lossless round trips through a FacetAccessType when converting back to
// the type of its original facet value.
//
// Given a symbolic facet value X, if a FacetAccessType(X) is converted to
// the type of X, we make the past introduction of the FacetAccessType
// preserve the original facet value by converting back into that original
// facet value. This is only needed when the (facet type) types match
// exactly, which allows the result to have equality with the original
// facet value.
//
// ```
// fn F(A:! Interface, B:! A) {
// // typeof(B) is a FacetAccessType(A). We want the following to be
// // true:
// (typeof(B) as typeof(A)) == A;
// }
// ```
//
// See also test:
// facet_access_type_converts_back_to_original_facet_value.carbon
auto facet_value_inst_id = facet_access_type_inst->facet_value_inst_id;
if (sem_ir.insts().Get(facet_value_inst_id).type_id() == target.type_id) {
return facet_value_inst_id;
Expand Down
Loading
Loading