Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 0 additions & 3 deletions toolchain/check/convert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1225,9 +1225,6 @@ static auto PerformBuiltinConversion(
// form. We can skip past the whole impl lookup step then and do that
// here.
//
// See also test:
// facet_access_type_converts_back_to_original_facet_value.carbon
//
// TODO: This instruction is going to become a `SymbolicBindingType`, so
// we'll need to handle that instead.
auto const_type_inst_id =
Expand Down
14 changes: 6 additions & 8 deletions toolchain/check/eval_inst.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,14 +210,12 @@ auto EvalConstantInst(Context& context, SemIR::FacetValue inst)
if (auto access =
context.insts().TryGetAs<SemIR::FacetAccessType>(inst.type_inst_id)) {
auto bind_id = access->facet_value_inst_id;
auto bind = context.insts().Get(bind_id);
if (bind.Is<SemIR::BindSymbolicName>()) {
// If the FacetTypes are the same, then the FacetValue didn't add/remove
// any witnesses.
if (bind.type_id() == inst.type_id) {
return ConstantEvalResult::Existing(
context.constant_values().Get(bind_id));
}
auto bind = context.insts().TryGetAs<SemIR::BindSymbolicName>(bind_id);
// If the FacetTypes are the same, then the FacetValue didn't add/remove
// any witnesses.
if (bind.has_value() && bind->type_id == inst.type_id) {
return ConstantEvalResult::Existing(
context.constant_values().Get(bind_id));
}
}

Expand Down
15 changes: 13 additions & 2 deletions toolchain/check/impl_lookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -545,8 +545,19 @@ static auto GetOrAddLookupImplWitness(Context& context, SemIR::LocId loc_id,
// Returns true if the `Self` should impl `Destroy`.
static auto TypeCanDestroy(Context& context,
SemIR::ConstantId query_self_const_id) -> bool {
auto inst = context.insts().Get(
context.constant_values().GetInstId(query_self_const_id));
auto inst = context.insts().Get(context.constant_values().GetInstId(
GetCanonicalizedFacetOrTypeValue(context, query_self_const_id)));

// For facet values, look if the FacetType provides the same.
if (auto facet_type =
context.types().TryGetAs<SemIR::FacetType>(inst.type_id())) {
const auto& info = context.facet_types().Get(facet_type->facet_type_id);
if (info.builtin_constraint_mask.HasAnyOf(
SemIR::BuiltinConstraintMask::TypeCanDestroy)) {
return true;
}
}

CARBON_KIND_SWITCH(inst) {
case CARBON_KIND(SemIR::ClassType class_type): {
auto class_info = context.classes().Get(class_type.class_id);
Expand Down
15 changes: 15 additions & 0 deletions toolchain/check/testdata/builtins/type/can_destroy.carbon
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,21 @@ fn G() {
//@dump-sem-ir-end
}

// --- symbolic.carbon
library "[[@TEST_NAME]]";

interface Z {}

fn CanDestroy() -> type = "type.can_destroy";

fn G(U:! CanDestroy()) {}

fn F(T:! Z & CanDestroy()) {
// Requires a conversion (and thus impl lookup into `T`) since `T` and `U`
// have different (but compatible) facet types.
G(T);
}

// --- fail_incomplete.carbon
library "[[@TEST_NAME]]";

Expand Down
Loading