mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 18:51:11 +01:00
This performs `.Self` substitution in a single step, for the whole facet type, instead of doing it individually for each constraint visited in the top-level facet type. Then we don't need to track state to avoid subst in constraints that come from other named constraints. The semir changes are because we now generate a whole other FacetType from the substitution.
91 lines
4.1 KiB
C++
91 lines
4.1 KiB
C++
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
// Exceptions. See /LICENSE for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
#ifndef CARBON_TOOLCHAIN_CHECK_PERIOD_SELF_H_
|
|
#define CARBON_TOOLCHAIN_CHECK_PERIOD_SELF_H_
|
|
|
|
#include "toolchain/check/context.h"
|
|
#include "toolchain/check/subst.h"
|
|
#include "toolchain/sem_ir/ids.h"
|
|
|
|
namespace Carbon::Check {
|
|
|
|
// Introduce `.Self` as a symbolic binding into the current scope, and return
|
|
// the `SymbolicBinding` instruction.
|
|
//
|
|
// The type of `.Self` must be a `FacetType`, so that it gets wrapped in
|
|
// `FacetAccessType` when used in a type position, such as in `U:! I(.Self)`.
|
|
// This allows substitution with other facet values without requiring an
|
|
// additional `FacetAccessType` to be inserted.
|
|
auto MakePeriodSelfFacetValue(Context& context, SemIR::LocId loc_id,
|
|
SemIR::TypeId self_type_id) -> SemIR::InstId;
|
|
|
|
enum class SubstPeriodSelfBehaviour {
|
|
ImplicitOnly,
|
|
ExplicitOnly,
|
|
All,
|
|
};
|
|
|
|
using SubstPeriodSelfRebuildInst =
|
|
llvm::function_ref<auto(SemIR::Inst)->SemIR::InstId>;
|
|
|
|
// Replace `.Self` references in `const_id` with `period_self_replacement_id`.
|
|
//
|
|
// The `behaviour` specifies if all `.Self` are replaced or just implicit use in
|
|
// designators. The `rebuild` callback can optionally be specified to override
|
|
// how an instruction is re-constructed to form an InstId after replacement. It
|
|
// can return None to fall back to the default of evaluating the inst.
|
|
auto SubstPeriodSelf(
|
|
Context& context, SemIR::LocId loc_id, SemIR::ConstantId const_id,
|
|
SemIR::ConstantId period_self_replacement_id,
|
|
SubstPeriodSelfBehaviour behaviour = SubstPeriodSelfBehaviour::All,
|
|
SubstPeriodSelfRebuildInst rebuild = nullptr) -> SemIR::ConstantId;
|
|
|
|
// Replace `.Self` references in the specific of the interface or named
|
|
// constraint with `period_self_replacement_id`.
|
|
//
|
|
// The `behaviour` specifies if all `.Self` are replaced or just implicit use in
|
|
// designators. The `rebuild` callback can optionally be specified to override
|
|
// how an instruction is re-constructed to form an InstId after replacement. It
|
|
// can return None to fall back to the default of evaluating the inst.
|
|
auto SubstPeriodSelf(
|
|
Context& context, SemIR::LocId loc_id, SemIR::SpecificInterface interface,
|
|
SemIR::ConstantId period_self_replacement_id,
|
|
SubstPeriodSelfBehaviour behaviour = SubstPeriodSelfBehaviour::All,
|
|
SubstPeriodSelfRebuildInst rebuild = nullptr) -> SemIR::SpecificInterface;
|
|
auto SubstPeriodSelf(
|
|
Context& context, SemIR::LocId loc_id,
|
|
SemIR::SpecificNamedConstraint constraint,
|
|
SemIR::ConstantId period_self_replacement_id,
|
|
SubstPeriodSelfBehaviour behaviour = SubstPeriodSelfBehaviour::All,
|
|
SubstPeriodSelfRebuildInst rebuild = nullptr)
|
|
-> SemIR::SpecificNamedConstraint;
|
|
|
|
// Replace `.Self` references with the self-type. The `facet_type_inst_id` must
|
|
// be a `FacetType` instruction (or error).
|
|
//
|
|
// The implicit `.Self` in designators is not replaced in rewrite constraints,
|
|
// to allow for rewrite constraint resolution to recognise the designators.
|
|
// Later use of rewrite constraints requires further `.Self` replacement.
|
|
//
|
|
// Unlike SubstPeriodSelf, which works with constant values and thus canonical
|
|
// instructions, this operation can be done for non-canonical facet types. A new
|
|
// instruction is added for the output FacetType if anything does get replaced,
|
|
// and the original instruction id is preserved otherwise.
|
|
auto SubstPeriodSelfInFacetType(Context& context, SemIR::LocId loc_id,
|
|
SemIR::InstId self_inst_id,
|
|
SemIR::TypeInstId facet_type_inst_id)
|
|
-> SemIR::TypeInstId;
|
|
|
|
// Returns whether the constant value of `inst_id` is a reference to `.Self`.
|
|
//
|
|
// If `canonicalize` is true, look at the constant value of `inst_id` and get
|
|
// the canonicalized facet or type to look through FacetAccessType.
|
|
auto IsPeriodSelf(Context& context, SemIR::InstId inst_id,
|
|
bool canonicalize = true) -> bool;
|
|
|
|
} // namespace Carbon::Check
|
|
|
|
#endif // CARBON_TOOLCHAIN_CHECK_PERIOD_SELF_H_
|