period_self.h 4.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #ifndef CARBON_TOOLCHAIN_CHECK_PERIOD_SELF_H_
  5. #define CARBON_TOOLCHAIN_CHECK_PERIOD_SELF_H_
  6. #include "toolchain/check/context.h"
  7. #include "toolchain/check/subst.h"
  8. #include "toolchain/sem_ir/ids.h"
  9. namespace Carbon::Check {
  10. // Introduce `.Self` as a symbolic binding into the current scope, and return
  11. // the `SymbolicBinding` instruction.
  12. //
  13. // The type of `.Self` must be a `FacetType`, so that it gets wrapped in
  14. // `FacetAccessType` when used in a type position, such as in `U:! I(.Self)`.
  15. // This allows substitution with other facet values without requiring an
  16. // additional `FacetAccessType` to be inserted.
  17. auto MakePeriodSelfFacetValue(Context& context, SemIR::TypeId self_type_id)
  18. -> SemIR::InstId;
  19. class SubstPeriodSelfCallbacks : public SubstInstCallbacks {
  20. public:
  21. explicit SubstPeriodSelfCallbacks(
  22. Context* context, SemIR::LocId loc_id,
  23. SemIR::ConstantId period_self_replacement_id);
  24. auto Subst(SemIR::InstId& inst_id) -> SubstResult override;
  25. auto Rebuild(SemIR::InstId orig_inst_id, SemIR::Inst new_inst)
  26. -> SemIR::InstId override;
  27. virtual auto ShouldReplace(bool /*implicit*/) -> bool { return true; }
  28. auto loc_id() const -> SemIR::LocId { return loc_id_; }
  29. auto period_self_replacement_id() const -> SemIR::ConstantId {
  30. return period_self_replacement_id_;
  31. }
  32. private:
  33. auto GetReplacement(SemIR::InstId period_self, bool implicit)
  34. -> SemIR::InstId;
  35. auto ConvertReplacement(SemIR::InstId replacement_self_inst_id,
  36. SemIR::TypeId replacement_type_id,
  37. SemIR::TypeId period_self_type_id) -> SemIR::InstId;
  38. SemIR::LocId loc_id_;
  39. SemIR::ConstantId period_self_replacement_id_;
  40. // The last output of GetReplacement().
  41. SemIR::InstId cached_replacement_id_ = SemIR::InstId::None;
  42. // The type of the last output of GetReplacement(). If the type of `.Self`
  43. // matches, we can reuse the `cached_replacement_id_`.
  44. SemIR::TypeId cached_replacement_type_id_ = SemIR::TypeId::None;
  45. };
  46. // Replace all `.Self` references in `const_id`. The `callbacks` specifies the
  47. // facet to replace them with.
  48. auto SubstPeriodSelf(Context& context, SubstPeriodSelfCallbacks& callbacks,
  49. SemIR::ConstantId const_id) -> SemIR::ConstantId;
  50. // Replace all `.Self` references in the specific of the interface or named
  51. // constraint. The `callbacks` specifies the facet to replace them with.
  52. auto SubstPeriodSelf(Context& context, SubstPeriodSelfCallbacks& callbacks,
  53. SemIR::SpecificInterface interface)
  54. -> SemIR::SpecificInterface;
  55. auto SubstPeriodSelf(Context& context, SubstPeriodSelfCallbacks& callbacks,
  56. SemIR::SpecificNamedConstraint constraint)
  57. -> SemIR::SpecificNamedConstraint;
  58. // Returns whether the constant value of `inst_id` is a reference to `.Self`.
  59. //
  60. // If `canonicalize` is true, look at the constant value of `inst_id` and get
  61. // the canonicalized facet or type to look through FacetAccessType.
  62. auto IsPeriodSelf(Context& context, SemIR::InstId inst_id,
  63. bool canonicalize = true) -> bool;
  64. // Look for ambiguous `.Self` in a `T impls X where ...` statement. The given
  65. // inst ids are the non-canonical insts for the LHS and RHS of the `impls`
  66. // inside a `where` expression.
  67. //
  68. // If the LHS is not `.Self` and RHS contains a nested `where` expression, the
  69. // value of `.Self` becomes ambiguous on the RHS of the `where` (it could mean
  70. // either the original value or new value given by the LHS of the `impls`). Note
  71. // that implicit `.Self` references are never ambiguous, they always refer to
  72. // the innermost value that `.Self` could refer to.
  73. //
  74. // Returns true if an error was diagnosed.
  75. auto FindAndDiagnoseAmbiguousPeriodSelf(Context& context,
  76. SemIR::InstId impls_lhs_id,
  77. SemIR::InstId impls_rhs_id) -> bool;
  78. } // namespace Carbon::Check
  79. #endif // CARBON_TOOLCHAIN_CHECK_PERIOD_SELF_H_