mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 22:02:23 +01:00
Add facet type values and an instruction that produces them (#4460)
Still to do: * Represent facet type values in a canonical form * Produce & consume facet type values instead of interface values * `type` should be associated with a canonical facet type value * Support `&` on facet type values * Type check and enforce requirements in facet types --------- Co-authored-by: Josh L <josh11b@users.noreply.github.com>
This commit is contained in:
@@ -126,6 +126,9 @@ class EvalContext {
|
||||
auto interfaces() -> const ValueStore<SemIR::InterfaceId>& {
|
||||
return sem_ir().interfaces();
|
||||
}
|
||||
auto facet_types() -> CanonicalValueStore<SemIR::FacetTypeId>& {
|
||||
return sem_ir().facet_types();
|
||||
}
|
||||
auto specifics() -> const SemIR::SpecificStore& {
|
||||
return sem_ir().specifics();
|
||||
}
|
||||
@@ -1106,6 +1109,20 @@ static auto MakeConstantForCall(EvalContext& eval_context, SemIRLoc loc,
|
||||
return SemIR::ConstantId::NotConstant;
|
||||
}
|
||||
|
||||
// Creates a FacetType constant.
|
||||
static auto MakeFacetTypeResult(Context& context,
|
||||
SemIR::TypeId base_facet_type_id,
|
||||
SemIR::InstBlockId requirement_block_id,
|
||||
Phase phase) -> SemIR::ConstantId {
|
||||
SemIR::FacetTypeId facet_type_id = context.sem_ir().facet_types().Add(
|
||||
SemIR::FacetTypeInfo{.base_facet_type_id = base_facet_type_id,
|
||||
.requirement_block_id = requirement_block_id});
|
||||
return MakeConstantResult(context,
|
||||
SemIR::FacetType{.type_id = SemIR::TypeId::TypeType,
|
||||
.facet_type_id = facet_type_id},
|
||||
phase);
|
||||
}
|
||||
|
||||
// Implementation for `TryEvalInst`, wrapping `Context` with `EvalContext`.
|
||||
static auto TryEvalInstInContext(EvalContext& eval_context,
|
||||
SemIR::InstId inst_id, SemIR::Inst inst)
|
||||
@@ -1287,6 +1304,23 @@ static auto TryEvalInstInContext(EvalContext& eval_context,
|
||||
Phase::Template);
|
||||
}
|
||||
|
||||
case CARBON_KIND(SemIR::FacetType facet_type): {
|
||||
SemIR::FacetTypeInfo info =
|
||||
eval_context.facet_types().Get(facet_type.facet_type_id);
|
||||
Phase phase = Phase::Template;
|
||||
SemIR::TypeId base_facet_type_id =
|
||||
GetConstantValue(eval_context, info.base_facet_type_id, &phase);
|
||||
// TODO: process & canonicalize requirements
|
||||
SemIR::InstBlockId requirement_block_id = info.requirement_block_id;
|
||||
// If nothing changed, can reuse this instruction.
|
||||
if (base_facet_type_id == info.base_facet_type_id &&
|
||||
requirement_block_id == info.requirement_block_id) {
|
||||
return MakeConstantResult(eval_context.context(), inst, phase);
|
||||
}
|
||||
return MakeFacetTypeResult(eval_context.context(), base_facet_type_id,
|
||||
requirement_block_id, phase);
|
||||
}
|
||||
|
||||
case CARBON_KIND(SemIR::InterfaceDecl interface_decl): {
|
||||
// If the interface has generic parameters, we don't produce an interface
|
||||
// type, but a callable whose return value is an interface type.
|
||||
@@ -1445,10 +1479,15 @@ static auto TryEvalInstInContext(EvalContext& eval_context,
|
||||
return eval_context.GetConstantValue(typed_inst.facet_id);
|
||||
}
|
||||
case CARBON_KIND(SemIR::WhereExpr typed_inst): {
|
||||
// TODO: This currently ignores the requirements and just produces the
|
||||
// left-hand type argument to the `where`.
|
||||
return eval_context.GetConstantValue(
|
||||
eval_context.insts().Get(typed_inst.period_self_id).type_id());
|
||||
SemIR::TypeId base_facet_type_id =
|
||||
eval_context.insts().Get(typed_inst.period_self_id).type_id();
|
||||
Phase phase = Phase::Template;
|
||||
base_facet_type_id =
|
||||
GetConstantValue(eval_context, base_facet_type_id, &phase);
|
||||
SemIR::InstBlockId requirement_block_id = typed_inst.requirements_id;
|
||||
// TODO: process & canonicalize requirements
|
||||
return MakeFacetTypeResult(eval_context.context(), base_facet_type_id,
|
||||
requirement_block_id, phase);
|
||||
}
|
||||
|
||||
// `not true` -> `false`, `not false` -> `true`.
|
||||
|
||||
Reference in New Issue
Block a user