| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- // 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::TypeId self_type_id)
- -> SemIR::InstId;
- class SubstPeriodSelfCallbacks : public SubstInstCallbacks {
- public:
- explicit SubstPeriodSelfCallbacks(
- Context* context, SemIR::LocId loc_id,
- SemIR::ConstantId period_self_replacement_id);
- auto Subst(SemIR::InstId& inst_id) -> SubstResult override;
- auto Rebuild(SemIR::InstId orig_inst_id, SemIR::Inst new_inst)
- -> SemIR::InstId override;
- virtual auto ShouldReplace(bool /*implicit*/) -> bool { return true; }
- auto loc_id() const -> SemIR::LocId { return loc_id_; }
- auto period_self_replacement_id() const -> SemIR::ConstantId {
- return period_self_replacement_id_;
- }
- private:
- auto GetReplacement(SemIR::InstId period_self, bool implicit)
- -> SemIR::InstId;
- auto ConvertReplacement(SemIR::InstId replacement_self_inst_id,
- SemIR::TypeId replacement_type_id,
- SemIR::TypeId period_self_type_id) -> SemIR::InstId;
- SemIR::LocId loc_id_;
- SemIR::ConstantId period_self_replacement_id_;
- // The last output of GetReplacement().
- SemIR::InstId cached_replacement_id_ = SemIR::InstId::None;
- // The type of the last output of GetReplacement(). If the type of `.Self`
- // matches, we can reuse the `cached_replacement_id_`.
- SemIR::TypeId cached_replacement_type_id_ = SemIR::TypeId::None;
- };
- // Replace all `.Self` references in `const_id`. The `callbacks` specifies the
- // facet to replace them with.
- auto SubstPeriodSelf(Context& context, SubstPeriodSelfCallbacks& callbacks,
- SemIR::ConstantId const_id) -> SemIR::ConstantId;
- // Replace all `.Self` references in the specific of the interface or named
- // constraint. The `callbacks` specifies the facet to replace them with.
- auto SubstPeriodSelf(Context& context, SubstPeriodSelfCallbacks& callbacks,
- SemIR::SpecificInterface interface)
- -> SemIR::SpecificInterface;
- auto SubstPeriodSelf(Context& context, SubstPeriodSelfCallbacks& callbacks,
- SemIR::SpecificNamedConstraint constraint)
- -> SemIR::SpecificNamedConstraint;
- // 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;
- // Look for ambiguous `.Self` in a `T impls X where ...` statement. The given
- // inst ids are the non-canonical insts for the LHS and RHS of the `impls`
- // inside a `where` expression.
- //
- // If the LHS is not `.Self` and RHS contains a nested `where` expression, the
- // value of `.Self` becomes ambiguous on the RHS of the `where` (it could mean
- // either the original value or new value given by the LHS of the `impls`). Note
- // that implicit `.Self` references are never ambiguous, they always refer to
- // the innermost value that `.Self` could refer to.
- //
- // Returns true if an error was diagnosed.
- auto FindAndDiagnoseAmbiguousPeriodSelf(Context& context,
- SemIR::InstId impls_lhs_id,
- SemIR::InstId impls_rhs_id) -> bool;
- } // namespace Carbon::Check
- #endif // CARBON_TOOLCHAIN_CHECK_PERIOD_SELF_H_
|