facet_type.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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_FACET_TYPE_H_
  5. #define CARBON_TOOLCHAIN_CHECK_FACET_TYPE_H_
  6. #include <compare>
  7. #include "toolchain/check/context.h"
  8. #include "toolchain/sem_ir/ids.h"
  9. namespace Carbon::Check {
  10. // Create a FacetType typed instruction object consisting of a single
  11. // interface. The `specific_id` specifies arguments in the case the interface is
  12. // generic.
  13. auto FacetTypeFromInterface(Context& context, SemIR::InterfaceId interface_id,
  14. SemIR::SpecificId specific_id) -> SemIR::FacetType;
  15. // Given an ImplWitnessAccessSubstituted, returns the InstId of the
  16. // ImplWitnessAccess. Otherwise, returns the input `inst_id` unchanged.
  17. //
  18. // This must be used when accessing the LHS of a rewrite constraint which has
  19. // not yet been resolved in order to preserve which associated constant is being
  20. // rewritten.
  21. auto GetImplWitnessAccessWithoutSubstitution(Context& context,
  22. SemIR::InstId inst_id)
  23. -> SemIR::InstId;
  24. // Creates a impl witness instruction for a facet type. The facet type is
  25. // required to be complete if `is_definition` is true or the facet type has
  26. // rewrites. Otherwise a placeholder witness is created, and
  27. // `AllocateFacetTypeImplWitness` can be used at the `impl` definition.
  28. //
  29. // Adds and returns an `ImplWitness` instruction (created with location set to
  30. // `witness_loc_id`) that shows "`Self` type" of type "facet type" (the value of
  31. // the `facet_type_inst_id` instruction) implements interface
  32. // `interface_to_witness`, which must be an interface required by "facet type"
  33. // (as determined by `RequireIdentifiedFacetType`). This witness reflects the
  34. // values assigned to associated constant members of that interface by rewrite
  35. // constraints in the facet type. `self_specific_id` will be the `specific_id`
  36. // of the resulting witness.
  37. //
  38. // `self_type_inst_id` is an instruction that evaluates to the `Self` type of
  39. // the facet type. For example, in `T:! X where ...`, we will bind the `.Self`
  40. // of the `where` facet type to `T`, and in `(X where ...) where ...`, we will
  41. // bind the inner `.Self` to the outer `.Self`.
  42. //
  43. // If the facet type contains a rewrite, we may have deferred converting the
  44. // rewritten value to the type of the associated constant. That conversion
  45. // will also be performed as part of resolution, and may depend on the
  46. // `Self` type.
  47. auto InitialFacetTypeImplWitness(
  48. Context& context, SemIR::LocId witness_loc_id,
  49. SemIR::TypeInstId facet_type_inst_id, SemIR::TypeInstId self_type_inst_id,
  50. const SemIR::SpecificInterface& interface_to_witness,
  51. SemIR::SpecificId self_specific_id, bool is_definition) -> SemIR::InstId;
  52. // Returns `true` if the facet type is complete. Otherwise issues a diagnostic
  53. // and returns `false`.
  54. auto RequireCompleteFacetTypeForImplDefinition(
  55. Context& context, SemIR::LocId loc_id, SemIR::TypeInstId facet_type_inst_id)
  56. -> bool;
  57. // Replaces the placeholder created by `InitialFacetTypeImplWitness` with an
  58. // empty witness table of the right size. Requires the interface designated by
  59. // `interface_id` to be complete.
  60. auto AllocateFacetTypeImplWitness(Context& context,
  61. SemIR::InterfaceId interface_id,
  62. SemIR::InstBlockId witness_id) -> void;
  63. // Perform rewrite constraint resolution for a facet type. The rewrite
  64. // constraints resolution is described here:
  65. // https://docs.carbon-lang.dev/docs/design/generics/appendix-rewrite-constraints.html#rewrite-constraint-resolution
  66. //
  67. // This function:
  68. // * Replaces the RHS of rewrite rules referring to `.Self` with the value
  69. // coming from other rewrite rules. For example in `.X = () and .Y = .X` the
  70. // result is `.X = () and .Y = ()`.
  71. // * Discards duplicate assignments to the same associated constant, such as in
  72. // `.X = () and .X = ()` which becomes just `.X = ()`.
  73. // * Diagnoses multiple assignments of different values to the same associated
  74. // constant such as `.X = () and .X = .Y`.
  75. // * Diagnoses cycles between rewrite rules such as `.X = .Y and .Y = .X` or
  76. // even `.X = .X`.
  77. //
  78. // The rewrite constraints in `rewrites` are modified in place and may be
  79. // reordered, with `ErrorInst` inserted when diagnosing errors.
  80. //
  81. // Returns false if resolve failed due to diagnosing an error. The resulting
  82. // value of the facet type should be an error constant.
  83. auto ResolveFacetTypeRewriteConstraints(
  84. Context& context, SemIR::LocId loc_id,
  85. llvm::SmallVector<SemIR::FacetTypeInfo::RewriteConstraint>& rewrites)
  86. -> bool;
  87. // Introduce `.Self` as a symbolic binding into the current scope, and return
  88. // the `BindSymbolicName` instruction.
  89. //
  90. // The `self_type_id` is either a facet type (as `FacetType`) or `type` (as
  91. // `TypeType`).
  92. auto MakePeriodSelfFacetValue(Context& context, SemIR::TypeId self_type_id)
  93. -> SemIR::InstId;
  94. } // namespace Carbon::Check
  95. #endif // CARBON_TOOLCHAIN_CHECK_FACET_TYPE_H_