interface.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  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. #include "toolchain/check/interface.h"
  5. #include <algorithm>
  6. #include <cstddef>
  7. #include "common/concepts.h"
  8. #include "toolchain/check/context.h"
  9. #include "toolchain/check/core_identifier.h"
  10. #include "toolchain/check/eval.h"
  11. #include "toolchain/check/generic.h"
  12. #include "toolchain/check/inst.h"
  13. #include "toolchain/check/merge.h"
  14. #include "toolchain/check/name_lookup.h"
  15. #include "toolchain/check/type.h"
  16. #include "toolchain/sem_ir/entity_with_params_base.h"
  17. #include "toolchain/sem_ir/ids.h"
  18. #include "toolchain/sem_ir/inst.h"
  19. #include "toolchain/sem_ir/typed_insts.h"
  20. namespace Carbon::Check {
  21. auto BuildAssociatedEntity(Context& context, SemIR::InterfaceId interface_id,
  22. SemIR::InstId decl_id) -> SemIR::InstId {
  23. auto& interface_info = context.interfaces().Get(interface_id);
  24. if (!interface_info.is_being_defined()) {
  25. // This should only happen if the interface is erroneously defined more than
  26. // once.
  27. // TODO: Find a way to CHECK this.
  28. return SemIR::ErrorInst::InstId;
  29. }
  30. // This associated entity is being declared as a member of the self specific
  31. // of the interface.
  32. auto interface_specific_id =
  33. context.generics().GetSelfSpecific(interface_info.generic_id);
  34. // Register this declaration as declaring an associated entity.
  35. auto index = SemIR::ElementIndex(
  36. context.args_type_info_stack().PeekCurrentBlockContents().size());
  37. context.args_type_info_stack().AddInstId(decl_id);
  38. // Name lookup for the declaration's name should name the associated entity,
  39. // not the declaration itself.
  40. auto type_id =
  41. GetAssociatedEntityType(context, interface_id, interface_specific_id);
  42. return AddInst<SemIR::AssociatedEntity>(
  43. context, SemIR::LocId(decl_id),
  44. {.type_id = type_id, .index = index, .decl_id = decl_id});
  45. }
  46. // Returns the `Self` binding for an interface, given a specific for the
  47. // interface and a generic for an associated entity within it.
  48. static auto GetSelfBinding(Context& context,
  49. SemIR::SpecificId interface_specific_id,
  50. SemIR::GenericId assoc_entity_generic_id)
  51. -> SemIR::InstId {
  52. const auto& generic = context.generics().Get(assoc_entity_generic_id);
  53. auto bindings = context.inst_blocks().Get(generic.bindings_id);
  54. auto interface_args_id =
  55. context.specifics().GetArgsOrEmpty(interface_specific_id);
  56. auto interface_args = context.inst_blocks().Get(interface_args_id);
  57. // The `Self` binding is the first binding after the interface's arguments.
  58. auto self_binding_id = bindings[interface_args.size()];
  59. // Check that we found the self binding. The binding might be a
  60. // `SymbolicBinding` or an `ImportRef` naming one.
  61. auto self_binding_const_inst_id =
  62. context.constant_values().GetConstantInstId(self_binding_id);
  63. auto bind_name_inst =
  64. context.insts().GetAs<SemIR::SymbolicBinding>(self_binding_const_inst_id);
  65. CARBON_CHECK(
  66. context.entity_names().Get(bind_name_inst.entity_name_id).name_id ==
  67. SemIR::NameId::SelfType,
  68. "Expected a Self binding, found {0}", bind_name_inst);
  69. return self_binding_id;
  70. }
  71. // Construct a facet value that can be used for the `Self` binding of entities
  72. // inside an interface.
  73. //
  74. // The `interface_specific_id` is the specific of the interface around the
  75. // `Self`. The `generic_id` is for member of the interface that the `Self` value
  76. // will be for. The `self_witness_id` is an impl witness for the interface that
  77. // the `self_type_id` implements that interface. It should come from an impl
  78. // definition with the given self-type and the interface as its constraint.
  79. //
  80. // The returned facet value can be used as the `Self` value in a specific for
  81. // the generic member of the interface, and can appear in its specific. As such,
  82. // this is a building block of GetSelfSpecificForInterfaceMemberWithSelfType.
  83. static auto GetSelfFacetValueForInterfaceMemberSpecific(
  84. Context& context, SemIR::SpecificId interface_specific_id,
  85. SemIR::GenericId generic_id, SemIR::TypeId self_type_id,
  86. SemIR::InstId self_witness_id) -> SemIR::InstId {
  87. auto self_binding_id =
  88. GetSelfBinding(context, interface_specific_id, generic_id);
  89. auto self_facet_type_id = SemIR::GetTypeOfInstInSpecific(
  90. context.sem_ir(), interface_specific_id, self_binding_id);
  91. // Create a facet value to be the value of `Self` in the interface.
  92. // TODO: Pass this in instead of creating it here. The caller sometimes
  93. // already has a facet value.
  94. auto type_inst_id = context.types().GetInstId(self_type_id);
  95. auto witnesses_block_id =
  96. context.inst_blocks().AddCanonical({self_witness_id});
  97. auto self_value_const_id = TryEvalInst(
  98. context, SemIR::FacetValue{.type_id = self_facet_type_id,
  99. .type_inst_id = type_inst_id,
  100. .witnesses_block_id = witnesses_block_id});
  101. return context.constant_values().GetInstId(self_value_const_id);
  102. }
  103. // Builds and returns the argument list from `interface_specific_id` with a
  104. // value for the `Self` parameter of `generic_id` appended.
  105. static auto GetGenericArgsWithSelfType(Context& context,
  106. SemIR::SpecificId interface_specific_id,
  107. SemIR::GenericId generic_id,
  108. SemIR::TypeId self_type_id,
  109. SemIR::InstId witness_inst_id,
  110. std::size_t reserve_args_size = 0)
  111. -> llvm::SmallVector<SemIR::InstId> {
  112. auto interface_args_id =
  113. context.specifics().GetArgsOrEmpty(interface_specific_id);
  114. auto interface_args = context.inst_blocks().Get(interface_args_id);
  115. llvm::SmallVector<SemIR::InstId> arg_ids;
  116. arg_ids.reserve(std::max(reserve_args_size, interface_args.size() + 1));
  117. // Start with the enclosing arguments from the interface.
  118. llvm::append_range(arg_ids, interface_args);
  119. // Add the `Self` argument.
  120. arg_ids.push_back(GetSelfFacetValueForInterfaceMemberSpecific(
  121. context, interface_specific_id, generic_id, self_type_id,
  122. witness_inst_id));
  123. return arg_ids;
  124. }
  125. auto GetSelfSpecificForInterfaceMemberWithSelfType(
  126. Context& context, SemIR::LocId loc_id,
  127. SemIR::SpecificId interface_specific_id, SemIR::GenericId generic_id,
  128. SemIR::SpecificId enclosing_specific_id, SemIR::TypeId self_type_id,
  129. SemIR::InstId witness_inst_id) -> SemIR::SpecificId {
  130. const auto& generic = context.generics().Get(generic_id);
  131. auto self_specific_args = context.inst_blocks().Get(
  132. context.specifics().Get(generic.self_specific_id).args_id);
  133. auto arg_ids = GetGenericArgsWithSelfType(
  134. context, interface_specific_id, generic_id, self_type_id, witness_inst_id,
  135. self_specific_args.size());
  136. // Determine the number of specific arguments that enclose the point where
  137. // this self specific will be used from. In an impl, this will be the number
  138. // of parameters that the impl has.
  139. int num_enclosing_specific_args =
  140. context.inst_blocks()
  141. .Get(context.specifics().GetArgsOrEmpty(enclosing_specific_id))
  142. .size();
  143. // The index of each remaining generic parameter is adjusted to match the
  144. // numbering at the point where the self specific is used.
  145. int index_delta = num_enclosing_specific_args - arg_ids.size();
  146. // Take any trailing argument values from the self specific.
  147. // TODO: If these refer to outer arguments, for example in their types, we may
  148. // need to perform extra substitutions here.
  149. for (auto arg_id : self_specific_args.drop_front(arg_ids.size())) {
  150. auto new_arg_id = context.constant_values().GetConstantInstId(arg_id);
  151. if (index_delta) {
  152. // If this parameter would have a new index in the context described by
  153. // `enclosing_specific_id`, form a new binding with an adjusted index.
  154. auto bind_name = context.insts().GetAs<SemIR::SymbolicBinding>(
  155. context.constant_values().GetConstantInstId(arg_id));
  156. auto entity_name = context.entity_names().Get(bind_name.entity_name_id);
  157. entity_name.bind_index_value += index_delta;
  158. CARBON_CHECK(entity_name.bind_index_value >= 0);
  159. bind_name.entity_name_id =
  160. context.entity_names().AddCanonical(entity_name);
  161. new_arg_id =
  162. context.constant_values().GetInstId(TryEvalInst(context, bind_name));
  163. }
  164. arg_ids.push_back(new_arg_id);
  165. }
  166. return MakeSpecific(context, loc_id, generic_id, arg_ids);
  167. }
  168. auto GetTypeForSpecificAssociatedEntity(Context& context, SemIR::LocId loc_id,
  169. SemIR::SpecificId interface_specific_id,
  170. SemIR::InstId decl_id,
  171. SemIR::TypeId self_type_id,
  172. SemIR::InstId self_witness_id)
  173. -> SemIR::TypeId {
  174. auto decl_constant_inst_id =
  175. context.constant_values().GetConstantInstId(decl_id);
  176. if (decl_constant_inst_id == SemIR::ErrorInst::InstId) {
  177. return SemIR::ErrorInst::TypeId;
  178. }
  179. auto decl = context.insts().Get(decl_constant_inst_id);
  180. if (auto assoc_const = decl.TryAs<SemIR::AssociatedConstantDecl>()) {
  181. // Form a specific for the associated constant, and grab the type from
  182. // there.
  183. auto generic_id = context.associated_constants()
  184. .Get(assoc_const->assoc_const_id)
  185. .generic_id;
  186. auto arg_ids =
  187. GetGenericArgsWithSelfType(context, interface_specific_id, generic_id,
  188. self_type_id, self_witness_id);
  189. auto const_specific_id = MakeSpecific(context, loc_id, generic_id, arg_ids);
  190. return SemIR::GetTypeOfInstInSpecific(context.sem_ir(), const_specific_id,
  191. decl_id);
  192. }
  193. if (auto fn = context.types().TryGetAs<SemIR::FunctionType>(decl.type_id())) {
  194. // Form the type of the function within the interface, and attach the `Self`
  195. // type.
  196. auto interface_fn_type_id = SemIR::GetTypeOfInstInSpecific(
  197. context.sem_ir(), interface_specific_id, decl_id);
  198. auto self_facet_id = GetSelfFacetValueForInterfaceMemberSpecific(
  199. context, interface_specific_id,
  200. context.functions().Get(fn->function_id).generic_id, self_type_id,
  201. self_witness_id);
  202. return GetFunctionTypeWithSelfType(
  203. context, context.types().GetInstId(interface_fn_type_id),
  204. self_facet_id);
  205. }
  206. CARBON_FATAL("Unexpected kind for associated constant {0}", decl);
  207. }
  208. auto AddSelfGenericParameter(Context& context, SemIR::LocId definition_loc_id,
  209. SemIR::TypeId type_id, SemIR::NameScopeId scope_id,
  210. bool is_template) -> SemIR::InstId {
  211. auto entity_name_id = context.entity_names().AddSymbolicBindingName(
  212. SemIR::NameId::SelfType, scope_id,
  213. context.scope_stack().AddCompileTimeBinding(), is_template);
  214. // Because there is no equivalent non-symbolic value, we use `None` as
  215. // the `value_id` on the `SymbolicBinding`.
  216. auto self_param_inst_id =
  217. AddInst<SemIR::SymbolicBinding>(context, definition_loc_id,
  218. {.type_id = type_id,
  219. .entity_name_id = entity_name_id,
  220. .value_id = SemIR::InstId::None});
  221. context.scope_stack().PushCompileTimeBinding(self_param_inst_id);
  222. context.name_scopes().AddRequiredName(scope_id, SemIR::NameId::SelfType,
  223. self_param_inst_id);
  224. return self_param_inst_id;
  225. }
  226. template <typename EntityT>
  227. requires std::same_as<EntityT, SemIR::Interface>
  228. static auto TryGetEntity(Context& context, SemIR::Inst inst)
  229. -> const SemIR::EntityWithParamsBase* {
  230. if (auto decl = inst.TryAs<SemIR::InterfaceDecl>()) {
  231. return &context.interfaces().Get(decl->interface_id);
  232. } else {
  233. return nullptr;
  234. }
  235. }
  236. template <typename EntityT>
  237. requires std::same_as<EntityT, SemIR::NamedConstraint>
  238. static auto TryGetEntity(Context& context, SemIR::Inst inst)
  239. -> const SemIR::EntityWithParamsBase* {
  240. if (auto decl = inst.TryAs<SemIR::NamedConstraintDecl>()) {
  241. return &context.named_constraints().Get(decl->named_constraint_id);
  242. } else {
  243. return nullptr;
  244. }
  245. }
  246. template <typename EntityT>
  247. requires std::same_as<EntityT, SemIR::Interface>
  248. static constexpr auto DeclTokenKind() -> Lex::TokenKind {
  249. return Lex::TokenKind::Interface;
  250. }
  251. template <typename EntityT>
  252. requires std::same_as<EntityT, SemIR::NamedConstraint>
  253. static constexpr auto DeclTokenKind() -> Lex::TokenKind {
  254. return Lex::TokenKind::Constraint;
  255. }
  256. template <typename EntityT>
  257. requires SameAsOneOf<EntityT, SemIR::Interface, SemIR::NamedConstraint>
  258. auto TryGetExistingDecl(Context& context, const NameComponent& name,
  259. SemIR::ScopeLookupResult lookup_result,
  260. const EntityT& entity, bool is_definition)
  261. -> std::optional<SemIR::Inst> {
  262. if (lookup_result.is_poisoned()) {
  263. // This is a declaration of a poisoned name.
  264. DiagnosePoisonedName(context, name.name_id,
  265. lookup_result.poisoning_loc_id(), name.name_loc_id);
  266. return std::nullopt;
  267. }
  268. if (!lookup_result.is_found()) {
  269. return std::nullopt;
  270. }
  271. SemIR::InstId existing_id = lookup_result.target_inst_id();
  272. SemIR::Inst existing_decl_inst = context.insts().Get(existing_id);
  273. const auto* existing_decl_entity =
  274. TryGetEntity<EntityT>(context, existing_decl_inst);
  275. if (!existing_decl_entity) {
  276. // This is a redeclaration with a different entity kind.
  277. DiagnoseDuplicateName(context, name.name_id, name.name_loc_id,
  278. SemIR::LocId(existing_id));
  279. return std::nullopt;
  280. }
  281. if (!CheckRedeclParamsMatch(
  282. context,
  283. DeclParams(SemIR::LocId(entity.latest_decl_id()),
  284. name.first_param_node_id, name.last_param_node_id,
  285. name.implicit_param_patterns_id, name.param_patterns_id),
  286. DeclParams(*existing_decl_entity))) {
  287. // Mismatch is diagnosed already if found.
  288. return std::nullopt;
  289. }
  290. // TODO: This should be refactored a little, particularly for
  291. // prev_import_ir_id. See similar logic for classes and functions, which
  292. // might also be refactored to merge.
  293. DiagnoseIfInvalidRedecl(
  294. context, DeclTokenKind<EntityT>(), existing_decl_entity->name_id,
  295. RedeclInfo(entity, SemIR::LocId(entity.latest_decl_id()), is_definition),
  296. RedeclInfo(*existing_decl_entity,
  297. SemIR::LocId(existing_decl_entity->latest_decl_id()),
  298. existing_decl_entity->has_definition_started()),
  299. /*prev_import_ir_id=*/SemIR::ImportIRId::None);
  300. if (is_definition && existing_decl_entity->has_definition_started()) {
  301. // DiagnoseIfInvalidRedecl would diagnose an error in this case, since we'd
  302. // have two definitions. Given the declaration parts of the definitions
  303. // match, we would be able to use the prior declaration for error recovery,
  304. // except that having two definitions causes larger problems for generics.
  305. // All interfaces (and named constraints) are generic with an implicit Self
  306. // compile time binding.
  307. return std::nullopt;
  308. }
  309. // This is a matching redeclaration of an existing entity of the same type.
  310. return existing_decl_inst;
  311. }
  312. template auto TryGetExistingDecl(Context& context, const NameComponent& name,
  313. SemIR::ScopeLookupResult lookup_result,
  314. const SemIR::Interface& entity,
  315. bool is_definition)
  316. -> std::optional<SemIR::Inst>;
  317. template auto TryGetExistingDecl(Context& context, const NameComponent& name,
  318. SemIR::ScopeLookupResult lookup_result,
  319. const SemIR::NamedConstraint& entity,
  320. bool is_definition)
  321. -> std::optional<SemIR::Inst>;
  322. } // namespace Carbon::Check