type_completion.cpp 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093
  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/type_completion.h"
  5. #include "common/concepts.h"
  6. #include "llvm/ADT/SmallVector.h"
  7. #include "toolchain/base/kind_switch.h"
  8. #include "toolchain/check/cpp/import.h"
  9. #include "toolchain/check/facet_type.h"
  10. #include "toolchain/check/generic.h"
  11. #include "toolchain/check/inst.h"
  12. #include "toolchain/check/literal.h"
  13. #include "toolchain/check/type.h"
  14. #include "toolchain/diagnostics/emitter.h"
  15. #include "toolchain/diagnostics/format_providers.h"
  16. #include "toolchain/sem_ir/constant.h"
  17. #include "toolchain/sem_ir/facet_type_info.h"
  18. #include "toolchain/sem_ir/generic.h"
  19. #include "toolchain/sem_ir/ids.h"
  20. #include "toolchain/sem_ir/named_constraint.h"
  21. #include "toolchain/sem_ir/specific_interface.h"
  22. #include "toolchain/sem_ir/specific_named_constraint.h"
  23. #include "toolchain/sem_ir/type_info.h"
  24. #include "toolchain/sem_ir/typed_insts.h"
  25. namespace Carbon::Check {
  26. auto DiagnoseIncompleteClass(Context& context, SemIR::ClassId class_id)
  27. -> void {
  28. // The caller must provide context for any diagnostics in type completion.
  29. context.emitter().CheckHasContext();
  30. const auto& class_info = context.classes().Get(class_id);
  31. CARBON_CHECK(!class_info.is_complete(), "Class is not incomplete");
  32. if (class_info.has_definition_started()) {
  33. CARBON_DIAGNOSTIC(ClassIncompleteWithinDefinition, Error,
  34. "class is incomplete within its definition");
  35. context.emitter().Emit(class_info.definition_id,
  36. ClassIncompleteWithinDefinition);
  37. } else {
  38. CARBON_DIAGNOSTIC(ClassForwardDeclaredHere, Error,
  39. "class was forward declared here");
  40. context.emitter().Emit(class_info.latest_decl_id(),
  41. ClassForwardDeclaredHere);
  42. }
  43. }
  44. auto DiagnoseIncompleteInterface(Context& context,
  45. SemIR::InterfaceId interface_id) -> void {
  46. // The caller must provide context for any diagnostics in type completion.
  47. context.emitter().CheckHasContext();
  48. const auto& interface_info = context.interfaces().Get(interface_id);
  49. CARBON_CHECK(!interface_info.is_complete(), "Interface is not incomplete");
  50. if (interface_info.is_being_defined()) {
  51. CARBON_DIAGNOSTIC(InterfaceIncompleteWithinDefinition, Error,
  52. "interface is currently being defined");
  53. context.emitter().Emit(interface_info.definition_id,
  54. InterfaceIncompleteWithinDefinition);
  55. } else {
  56. CARBON_DIAGNOSTIC(InterfaceForwardDeclaredHere, Error,
  57. "interface was forward declared here");
  58. context.emitter().Emit(interface_info.latest_decl_id(),
  59. InterfaceForwardDeclaredHere);
  60. }
  61. }
  62. auto DiagnoseAbstractClass(Context& context, SemIR::ClassId class_id,
  63. bool direct_use) -> void {
  64. // The caller must provide context for any diagnostics in type completion.
  65. context.emitter().CheckHasContext();
  66. const auto& class_info = context.classes().Get(class_id);
  67. CARBON_CHECK(
  68. class_info.inheritance_kind == SemIR::Class::InheritanceKind::Abstract,
  69. "Class is not abstract");
  70. CARBON_DIAGNOSTIC(
  71. ClassAbstractHere, Error,
  72. "{0:=0:uses class that|=1:class} was declared abstract here",
  73. Diagnostics::IntAsSelect);
  74. context.emitter().Emit(class_info.definition_id, ClassAbstractHere,
  75. static_cast<int>(direct_use));
  76. }
  77. static auto DiagnoseIncompleteNamedConstraint(
  78. Context& context, SemIR::NamedConstraintId named_constraint_id) -> void {
  79. // The caller must provide context for any diagnostics in type completion.
  80. context.emitter().CheckHasContext();
  81. const auto& constraint = context.named_constraints().Get(named_constraint_id);
  82. CARBON_CHECK(!constraint.is_complete(), "Named constraint is not incomplete");
  83. if (constraint.is_being_defined()) {
  84. CARBON_DIAGNOSTIC(NamedConstraintIncompleteWithinDefinition, Error,
  85. "constraint is currently being defined");
  86. context.emitter().Emit(constraint.definition_id,
  87. NamedConstraintIncompleteWithinDefinition);
  88. } else {
  89. CARBON_DIAGNOSTIC(NamedConstraintForwardDeclaredHere, Error,
  90. "constraint was forward declared here");
  91. context.emitter().Emit(constraint.latest_decl_id(),
  92. NamedConstraintForwardDeclaredHere);
  93. }
  94. }
  95. // TODO: Have the resolved specific know whether any instructions in the
  96. // declaration or definition contain an ErrorInst, instead of having to do a
  97. // linear scan here.
  98. static auto SpecificContainsError(Context& context,
  99. SemIR::SpecificId specific_id) -> bool {
  100. if (!specific_id.has_value()) {
  101. return false;
  102. }
  103. const auto& specific = context.specifics().Get(specific_id);
  104. auto block_ids = {specific.decl_block_id, specific.definition_block_id};
  105. for (auto block_id : block_ids) {
  106. if (block_id.has_value()) {
  107. for (auto inst_id : context.inst_blocks().Get(block_id)) {
  108. if (context.constant_values().Get(inst_id) ==
  109. SemIR::ErrorInst::ConstantId) {
  110. return true;
  111. }
  112. }
  113. }
  114. }
  115. return false;
  116. }
  117. static auto RequireCompleteFacetType(Context& context, SemIR::LocId loc_id,
  118. const SemIR::FacetType& facet_type,
  119. bool diagnose) -> bool {
  120. const auto& facet_type_info =
  121. context.facet_types().Get(facet_type.facet_type_id);
  122. for (auto extends : facet_type_info.extend_constraints) {
  123. auto interface_id = extends.interface_id;
  124. const auto& interface = context.interfaces().Get(interface_id);
  125. if (!interface.is_complete()) {
  126. if (diagnose) {
  127. DiagnoseIncompleteInterface(context, interface_id);
  128. }
  129. return false;
  130. }
  131. if (interface.generic_id.has_value()) {
  132. ResolveSpecificDefinition(context, loc_id, extends.specific_id);
  133. if (SpecificContainsError(context, extends.specific_id)) {
  134. return false;
  135. }
  136. }
  137. auto interface_with_self_self_specific_args = context.inst_blocks().Get(
  138. context.specifics().GetArgsOrEmpty(context.generics().GetSelfSpecific(
  139. interface.generic_with_self_id)));
  140. auto self_facet = interface_with_self_self_specific_args.back();
  141. auto interface_with_self_specific_id = MakeSpecificWithInnerSelf(
  142. context, loc_id, interface.generic_id, interface.generic_with_self_id,
  143. extends.specific_id, context.constant_values().Get(self_facet));
  144. if (SpecificContainsError(context, interface_with_self_specific_id)) {
  145. return false;
  146. }
  147. }
  148. for (auto extends : facet_type_info.extend_named_constraints) {
  149. auto named_constraint_id = extends.named_constraint_id;
  150. const auto& constraint =
  151. context.named_constraints().Get(named_constraint_id);
  152. if (!constraint.is_complete()) {
  153. if (diagnose) {
  154. DiagnoseIncompleteNamedConstraint(context, named_constraint_id);
  155. }
  156. return false;
  157. }
  158. if (constraint.generic_id.has_value()) {
  159. ResolveSpecificDefinition(context, loc_id, extends.specific_id);
  160. if (SpecificContainsError(context, extends.specific_id)) {
  161. return false;
  162. }
  163. }
  164. auto constraint_with_self_self_specific_args = context.inst_blocks().Get(
  165. context.specifics().GetArgsOrEmpty(context.generics().GetSelfSpecific(
  166. constraint.generic_with_self_id)));
  167. auto self_facet = constraint_with_self_self_specific_args.back();
  168. auto constraint_with_self_specific_id = MakeSpecificWithInnerSelf(
  169. context, loc_id, constraint.generic_id, constraint.generic_with_self_id,
  170. extends.specific_id, context.constant_values().Get(self_facet));
  171. if (SpecificContainsError(context, constraint_with_self_specific_id)) {
  172. return false;
  173. }
  174. }
  175. return true;
  176. }
  177. namespace {
  178. // Worklist-based type completion mechanism.
  179. //
  180. // When attempting to complete a type, we may find other types that also need to
  181. // be completed: types nested within that type, and the value representation of
  182. // the type. In order to complete a type without recursing arbitrarily deeply,
  183. // we use a worklist of tasks:
  184. //
  185. // - An `AddNestedIncompleteTypes` step adds a task for all incomplete types
  186. // nested within a type to the work list.
  187. // - A `BuildInfo` step computes the `CompleteTypeInfo` for a type, once all of
  188. // its nested types are complete, and marks the type as complete.
  189. class TypeCompleter {
  190. public:
  191. // `context` mut not be null.
  192. TypeCompleter(Context* context, SemIR::LocId loc_id, bool diagnose)
  193. : context_(context), loc_id_(loc_id), diagnose_(diagnose) {}
  194. // Attempts to complete the given type. Returns true if it is now complete,
  195. // false if it could not be completed.
  196. auto Complete(SemIR::TypeId type_id) -> bool;
  197. private:
  198. enum class Phase : int8_t {
  199. // The next step is to add nested types to the list of types to complete.
  200. AddNestedIncompleteTypes,
  201. // The next step is to build the `CompleteTypeInfo` for the type.
  202. BuildInfo,
  203. };
  204. struct WorkItem {
  205. SemIR::TypeId type_id;
  206. Phase phase;
  207. };
  208. // Adds `type_id` to the work list, if it's not already complete.
  209. auto Push(SemIR::TypeId type_id) -> void;
  210. // Runs the next step.
  211. auto ProcessStep() -> bool;
  212. // Adds any types nested within `type_inst` that need to be complete for
  213. // `type_inst` to be complete to our work list.
  214. auto AddNestedIncompleteTypes(SemIR::Inst type_inst) -> bool;
  215. // Makes an empty value representation, which is used for types that have no
  216. // state, such as empty structs and tuples.
  217. auto MakeEmptyValueRepr() const -> SemIR::ValueRepr;
  218. // Makes a dependent value representation, which is used for symbolic types.
  219. auto MakeDependentValueRepr(SemIR::TypeId type_id) const -> SemIR::ValueRepr;
  220. // Makes a value representation that uses pass-by-copy, copying the given
  221. // type.
  222. auto MakeCopyValueRepr(SemIR::TypeId rep_id,
  223. SemIR::ValueRepr::AggregateKind aggregate_kind =
  224. SemIR::ValueRepr::NotAggregate) const
  225. -> SemIR::ValueRepr;
  226. // Makes a value representation that uses pass-by-address with the given
  227. // pointee type.
  228. auto MakePointerValueRepr(SemIR::TypeId pointee_id,
  229. SemIR::ValueRepr::AggregateKind aggregate_kind =
  230. SemIR::ValueRepr::NotAggregate) const
  231. -> SemIR::ValueRepr;
  232. // Gets the value representation of a nested type, which should already be
  233. // complete.
  234. auto GetNestedInfo(SemIR::TypeId nested_type_id) const
  235. -> SemIR::CompleteTypeInfo;
  236. template <typename InstT>
  237. requires(InstT::Kind.template IsAnyOf<
  238. SemIR::AutoType, SemIR::BoolType, SemIR::BoundMethodType,
  239. SemIR::CharLiteralType, SemIR::ErrorInst, SemIR::FacetType,
  240. SemIR::FloatLiteralType, SemIR::FloatType, SemIR::FormType,
  241. SemIR::IntType, SemIR::IntLiteralType, SemIR::NamespaceType,
  242. SemIR::PatternType, SemIR::PointerType,
  243. SemIR::RequireSpecificDefinitionType, SemIR::SpecificFunctionType,
  244. SemIR::TypeType, SemIR::VtableType, SemIR::WitnessType>())
  245. auto BuildInfoForInst(SemIR::TypeId type_id, InstT /*inst*/) const
  246. -> SemIR::CompleteTypeInfo {
  247. return {.value_repr = MakeCopyValueRepr(type_id)};
  248. }
  249. auto BuildStructOrTupleValueRepr(size_t num_elements,
  250. SemIR::TypeId elementwise_rep,
  251. bool same_as_object_rep) const
  252. -> SemIR::ValueRepr;
  253. auto BuildInfoForInst(SemIR::TypeId type_id,
  254. SemIR::StructType struct_type) const
  255. -> SemIR::CompleteTypeInfo;
  256. auto BuildInfoForInst(SemIR::TypeId type_id,
  257. SemIR::TupleType tuple_type) const
  258. -> SemIR::CompleteTypeInfo;
  259. auto BuildInfoForInst(SemIR::TypeId type_id, SemIR::ArrayType /*inst*/) const
  260. -> SemIR::CompleteTypeInfo;
  261. auto BuildInfoForInst(SemIR::TypeId /*type_id*/, SemIR::ClassType inst) const
  262. -> SemIR::CompleteTypeInfo;
  263. template <typename InstT>
  264. requires(InstT::Kind.template IsAnyOf<
  265. SemIR::AssociatedEntityType, SemIR::CppOverloadSetType,
  266. SemIR::CppTemplateNameType, SemIR::FunctionType,
  267. SemIR::FunctionTypeWithSelfType, SemIR::GenericClassType,
  268. SemIR::GenericInterfaceType, SemIR::GenericNamedConstraintType,
  269. SemIR::InstType, SemIR::UnboundElementType, SemIR::WhereExpr>())
  270. auto BuildInfoForInst(SemIR::TypeId /*type_id*/, InstT /*inst*/) const
  271. -> SemIR::CompleteTypeInfo {
  272. // These types have no runtime operations, so we use an empty value
  273. // representation.
  274. //
  275. // TODO: There is information we could model here:
  276. // - For an interface, we could use a witness.
  277. // - For an associated entity, we could use an index into the witness.
  278. // - For an unbound element, we could use an index or offset.
  279. return {.value_repr = MakeEmptyValueRepr()};
  280. }
  281. auto BuildInfoForInst(SemIR::TypeId /*type_id*/, SemIR::ConstType inst) const
  282. -> SemIR::CompleteTypeInfo;
  283. auto BuildInfoForInst(SemIR::TypeId type_id,
  284. SemIR::CustomLayoutType inst) const
  285. -> SemIR::CompleteTypeInfo;
  286. auto BuildInfoForInst(SemIR::TypeId /*type_id*/,
  287. SemIR::MaybeUnformedType inst) const
  288. -> SemIR::CompleteTypeInfo;
  289. auto BuildInfoForInst(SemIR::TypeId /*type_id*/,
  290. SemIR::PartialType inst) const
  291. -> SemIR::CompleteTypeInfo;
  292. auto BuildInfoForInst(SemIR::TypeId /*type_id*/,
  293. SemIR::ImplWitnessAssociatedConstant inst) const
  294. -> SemIR::CompleteTypeInfo;
  295. template <typename InstT>
  296. requires(InstT::Kind.is_type() == SemIR::InstIsType::Never)
  297. auto BuildInfoForInst(SemIR::TypeId /*type_id*/, InstT inst) const
  298. -> SemIR::CompleteTypeInfo {
  299. CARBON_FATAL("Type refers to non-type inst {0}", inst);
  300. }
  301. template <typename InstT>
  302. requires(InstT::Kind.is_symbolic_when_type())
  303. auto BuildInfoForInst(SemIR::TypeId type_id, InstT /*inst*/) const
  304. -> SemIR::CompleteTypeInfo {
  305. return {.value_repr = MakeDependentValueRepr(type_id)};
  306. }
  307. // Builds and returns the `CompleteTypeInfo` for the given type. All nested
  308. // types, as found by AddNestedIncompleteTypes, are known to be complete.
  309. auto BuildInfo(SemIR::TypeId type_id, SemIR::Inst inst) const
  310. -> SemIR::CompleteTypeInfo;
  311. Context* context_;
  312. llvm::SmallVector<WorkItem> work_list_;
  313. SemIR::LocId loc_id_;
  314. bool diagnose_;
  315. };
  316. } // namespace
  317. auto TypeCompleter::Complete(SemIR::TypeId type_id) -> bool {
  318. Push(type_id);
  319. while (!work_list_.empty()) {
  320. if (!ProcessStep()) {
  321. return false;
  322. }
  323. }
  324. return true;
  325. }
  326. auto TypeCompleter::Push(SemIR::TypeId type_id) -> void {
  327. if (!context_->types().IsComplete(type_id)) {
  328. work_list_.push_back(
  329. {.type_id = type_id, .phase = Phase::AddNestedIncompleteTypes});
  330. }
  331. }
  332. auto TypeCompleter::ProcessStep() -> bool {
  333. auto [type_id, phase] = work_list_.back();
  334. // We might have enqueued the same type more than once. Just skip the
  335. // type if it's already complete.
  336. if (context_->types().IsComplete(type_id)) {
  337. work_list_.pop_back();
  338. return true;
  339. }
  340. auto inst_id = context_->types().GetTypeInstId(type_id);
  341. auto inst = context_->insts().Get(inst_id);
  342. auto old_work_list_size = work_list_.size();
  343. switch (phase) {
  344. case Phase::AddNestedIncompleteTypes:
  345. if (!AddNestedIncompleteTypes(inst)) {
  346. return false;
  347. }
  348. CARBON_CHECK(work_list_.size() >= old_work_list_size,
  349. "AddNestedIncompleteTypes should not remove work items");
  350. work_list_[old_work_list_size - 1].phase = Phase::BuildInfo;
  351. break;
  352. case Phase::BuildInfo: {
  353. auto info = BuildInfo(type_id, inst);
  354. context_->types().SetComplete(type_id, info);
  355. CARBON_CHECK(old_work_list_size == work_list_.size(),
  356. "BuildInfo should not change work items");
  357. work_list_.pop_back();
  358. // Also complete the value representation type, if necessary. This
  359. // should never fail: the value representation shouldn't require any
  360. // additional nested types to be complete.
  361. if (!context_->types().IsComplete(info.value_repr.type_id)) {
  362. work_list_.push_back(
  363. {.type_id = info.value_repr.type_id, .phase = Phase::BuildInfo});
  364. }
  365. // For a pointer representation, the pointee also needs to be complete.
  366. if (info.value_repr.kind == SemIR::ValueRepr::Pointer) {
  367. if (info.value_repr.type_id == SemIR::ErrorInst::TypeId) {
  368. break;
  369. }
  370. auto pointee_type_id =
  371. context_->sem_ir().GetPointeeType(info.value_repr.type_id);
  372. if (!context_->types().IsComplete(pointee_type_id)) {
  373. work_list_.push_back(
  374. {.type_id = pointee_type_id, .phase = Phase::BuildInfo});
  375. }
  376. }
  377. break;
  378. }
  379. }
  380. return true;
  381. }
  382. auto TypeCompleter::AddNestedIncompleteTypes(SemIR::Inst type_inst) -> bool {
  383. CARBON_KIND_SWITCH(type_inst) {
  384. case CARBON_KIND(SemIR::ArrayType inst): {
  385. Push(context_->types().GetTypeIdForTypeInstId(inst.element_type_inst_id));
  386. break;
  387. }
  388. case CARBON_KIND(SemIR::StructType inst): {
  389. for (auto field : context_->struct_type_fields().Get(inst.fields_id)) {
  390. Push(context_->types().GetTypeIdForTypeInstId(field.type_inst_id));
  391. }
  392. break;
  393. }
  394. case CARBON_KIND(SemIR::TupleType inst): {
  395. for (auto element_type_id : context_->types().GetBlockAsTypeIds(
  396. context_->inst_blocks().Get(inst.type_elements_id))) {
  397. Push(element_type_id);
  398. }
  399. break;
  400. }
  401. case CARBON_KIND(SemIR::ClassType inst): {
  402. auto& class_info = context_->classes().Get(inst.class_id);
  403. // If the class was imported from C++, ask Clang to try to complete it.
  404. if (!class_info.is_complete() && class_info.scope_id.has_value()) {
  405. auto& scope = context_->name_scopes().Get(class_info.scope_id);
  406. if (scope.clang_decl_context_id().has_value()) {
  407. if (!ImportClassDefinitionForClangDecl(
  408. *context_, inst.class_id, scope.clang_decl_context_id())) {
  409. // Clang produced a diagnostic. Don't produce one of our own.
  410. return false;
  411. }
  412. }
  413. }
  414. if (!class_info.is_complete()) {
  415. if (diagnose_) {
  416. DiagnoseIncompleteClass(*context_, inst.class_id);
  417. }
  418. return false;
  419. }
  420. if (inst.specific_id.has_value()) {
  421. ResolveSpecificDefinition(*context_, loc_id_, inst.specific_id);
  422. }
  423. if (auto adapted_type_id =
  424. class_info.GetAdaptedType(context_->sem_ir(), inst.specific_id);
  425. adapted_type_id.has_value()) {
  426. Push(adapted_type_id);
  427. } else {
  428. Push(class_info.GetObjectRepr(context_->sem_ir(), inst.specific_id));
  429. }
  430. break;
  431. }
  432. case CARBON_KIND(SemIR::ConstType inst): {
  433. Push(context_->types().GetTypeIdForTypeInstId(inst.inner_id));
  434. break;
  435. }
  436. case CARBON_KIND(SemIR::CustomLayoutType inst): {
  437. for (auto field : context_->struct_type_fields().Get(inst.fields_id)) {
  438. Push(context_->types().GetTypeIdForTypeInstId(field.type_inst_id));
  439. }
  440. break;
  441. }
  442. case CARBON_KIND(SemIR::MaybeUnformedType inst): {
  443. Push(context_->types().GetTypeIdForTypeInstId(inst.inner_id));
  444. break;
  445. }
  446. case CARBON_KIND(SemIR::PartialType inst): {
  447. Push(context_->types().GetTypeIdForTypeInstId(inst.inner_id));
  448. break;
  449. }
  450. case CARBON_KIND(SemIR::FacetType inst): {
  451. if (!RequireCompleteFacetType(*context_, loc_id_, inst, diagnose_)) {
  452. return false;
  453. }
  454. break;
  455. }
  456. default:
  457. break;
  458. }
  459. return true;
  460. }
  461. auto TypeCompleter::MakeEmptyValueRepr() const -> SemIR::ValueRepr {
  462. return {.kind = SemIR::ValueRepr::None,
  463. .type_id = GetTupleType(*context_, {})};
  464. }
  465. auto TypeCompleter::MakeDependentValueRepr(SemIR::TypeId type_id) const
  466. -> SemIR::ValueRepr {
  467. return {.kind = SemIR::ValueRepr::Dependent, .type_id = type_id};
  468. }
  469. auto TypeCompleter::MakeCopyValueRepr(
  470. SemIR::TypeId rep_id, SemIR::ValueRepr::AggregateKind aggregate_kind) const
  471. -> SemIR::ValueRepr {
  472. return {.kind = SemIR::ValueRepr::Copy,
  473. .aggregate_kind = aggregate_kind,
  474. .type_id = rep_id};
  475. }
  476. auto TypeCompleter::MakePointerValueRepr(
  477. SemIR::TypeId pointee_id,
  478. SemIR::ValueRepr::AggregateKind aggregate_kind) const -> SemIR::ValueRepr {
  479. // TODO: Should we add `const` qualification to `pointee_id`?
  480. return {.kind = SemIR::ValueRepr::Pointer,
  481. .aggregate_kind = aggregate_kind,
  482. .type_id = GetPointerType(
  483. *context_, context_->types().GetTypeInstId(pointee_id))};
  484. }
  485. auto TypeCompleter::GetNestedInfo(SemIR::TypeId nested_type_id) const
  486. -> SemIR::CompleteTypeInfo {
  487. CARBON_CHECK(context_->types().IsComplete(nested_type_id),
  488. "Nested type should already be complete");
  489. auto info = context_->types().GetCompleteTypeInfo(nested_type_id);
  490. CARBON_CHECK(info.value_repr.kind != SemIR::ValueRepr::Unknown,
  491. "Complete type should have a value representation");
  492. return info;
  493. }
  494. auto TypeCompleter::BuildStructOrTupleValueRepr(size_t num_elements,
  495. SemIR::TypeId elementwise_rep,
  496. bool same_as_object_rep) const
  497. -> SemIR::ValueRepr {
  498. SemIR::ValueRepr::AggregateKind aggregate_kind =
  499. same_as_object_rep ? SemIR::ValueRepr::ValueAndObjectAggregate
  500. : SemIR::ValueRepr::ValueAggregate;
  501. if (num_elements == 1) {
  502. // The value representation for a struct or tuple with a single element
  503. // is a struct or tuple containing the value representation of the
  504. // element.
  505. // TODO: Consider doing the same whenever `elementwise_rep` is
  506. // sufficiently small.
  507. return MakeCopyValueRepr(elementwise_rep, aggregate_kind);
  508. }
  509. // For a struct or tuple with multiple fields, we use a pointer
  510. // to the elementwise value representation.
  511. return MakePointerValueRepr(elementwise_rep, aggregate_kind);
  512. }
  513. auto TypeCompleter::BuildInfoForInst(SemIR::TypeId type_id,
  514. SemIR::StructType struct_type) const
  515. -> SemIR::CompleteTypeInfo {
  516. auto fields = context_->struct_type_fields().Get(struct_type.fields_id);
  517. if (fields.empty()) {
  518. return {.value_repr = MakeEmptyValueRepr()};
  519. }
  520. // Find the value representation for each field, and construct a struct
  521. // of value representations.
  522. llvm::SmallVector<SemIR::StructTypeField> value_rep_fields;
  523. value_rep_fields.reserve(fields.size());
  524. bool same_as_object_rep = true;
  525. SemIR::ClassId abstract_class_id = SemIR::ClassId::None;
  526. for (auto field : fields) {
  527. auto field_type_id =
  528. context_->types().GetTypeIdForTypeInstId(field.type_inst_id);
  529. auto field_info = GetNestedInfo(field_type_id);
  530. if (!field_info.value_repr.IsCopyOfObjectRepr(context_->sem_ir(),
  531. field_type_id)) {
  532. same_as_object_rep = false;
  533. field.type_inst_id =
  534. context_->types().GetTypeInstId(field_info.value_repr.type_id);
  535. }
  536. value_rep_fields.push_back(field);
  537. // Take the first non-None abstract_class_id, if any.
  538. if (field_info.abstract_class_id.has_value() &&
  539. !abstract_class_id.has_value()) {
  540. abstract_class_id = field_info.abstract_class_id;
  541. }
  542. }
  543. auto value_rep =
  544. same_as_object_rep
  545. ? type_id
  546. : GetStructType(
  547. *context_,
  548. context_->struct_type_fields().AddCanonical(value_rep_fields));
  549. return {.value_repr = BuildStructOrTupleValueRepr(fields.size(), value_rep,
  550. same_as_object_rep),
  551. .abstract_class_id = abstract_class_id};
  552. }
  553. auto TypeCompleter::BuildInfoForInst(SemIR::TypeId type_id,
  554. SemIR::TupleType tuple_type) const
  555. -> SemIR::CompleteTypeInfo {
  556. // TODO: Share more code with structs.
  557. auto elements = context_->inst_blocks().Get(tuple_type.type_elements_id);
  558. if (elements.empty()) {
  559. return {.value_repr = MakeEmptyValueRepr()};
  560. }
  561. // Find the value representation for each element, and construct a tuple
  562. // of value representations.
  563. llvm::SmallVector<SemIR::InstId> value_rep_elements;
  564. value_rep_elements.reserve(elements.size());
  565. bool same_as_object_rep = true;
  566. SemIR::ClassId abstract_class_id = SemIR::ClassId::None;
  567. for (auto element_type_id : context_->types().GetBlockAsTypeIds(elements)) {
  568. auto element_info = GetNestedInfo(element_type_id);
  569. if (!element_info.value_repr.IsCopyOfObjectRepr(context_->sem_ir(),
  570. element_type_id)) {
  571. same_as_object_rep = false;
  572. }
  573. value_rep_elements.push_back(
  574. context_->types().GetTypeInstId(element_info.value_repr.type_id));
  575. // Take the first non-None abstract_class_id, if any.
  576. if (element_info.abstract_class_id.has_value() &&
  577. !abstract_class_id.has_value()) {
  578. abstract_class_id = element_info.abstract_class_id;
  579. }
  580. }
  581. auto value_rep = same_as_object_rep
  582. ? type_id
  583. : GetTupleType(*context_, value_rep_elements);
  584. return {.value_repr = BuildStructOrTupleValueRepr(elements.size(), value_rep,
  585. same_as_object_rep),
  586. .abstract_class_id = abstract_class_id};
  587. }
  588. auto TypeCompleter::BuildInfoForInst(SemIR::TypeId type_id,
  589. SemIR::ArrayType /*inst*/) const
  590. -> SemIR::CompleteTypeInfo {
  591. // For arrays, it's convenient to always use a pointer representation,
  592. // even when the array has zero or one element, in order to support
  593. // indexing.
  594. return {.value_repr =
  595. MakePointerValueRepr(type_id, SemIR::ValueRepr::ObjectAggregate)};
  596. }
  597. auto TypeCompleter::BuildInfoForInst(SemIR::TypeId /*type_id*/,
  598. SemIR::ClassType inst) const
  599. -> SemIR::CompleteTypeInfo {
  600. auto& class_info = context_->classes().Get(inst.class_id);
  601. auto abstract_class_id =
  602. class_info.inheritance_kind == SemIR::Class::InheritanceKind::Abstract
  603. ? inst.class_id
  604. : SemIR::ClassId::None;
  605. // The value representation of an adapter is the value representation of
  606. // its adapted type.
  607. if (auto adapted_type_id =
  608. class_info.GetAdaptedType(context_->sem_ir(), inst.specific_id);
  609. adapted_type_id.has_value()) {
  610. auto info = GetNestedInfo(adapted_type_id);
  611. info.abstract_class_id = abstract_class_id;
  612. return info;
  613. }
  614. // Otherwise, the value representation for a class is a pointer to the
  615. // object representation.
  616. // TODO: Support customized value representations for classes.
  617. // TODO: Pick a better value representation when possible.
  618. return {.value_repr = MakePointerValueRepr(
  619. class_info.GetObjectRepr(context_->sem_ir(), inst.specific_id),
  620. SemIR::ValueRepr::ObjectAggregate),
  621. .abstract_class_id = abstract_class_id};
  622. }
  623. auto TypeCompleter::BuildInfoForInst(SemIR::TypeId /*type_id*/,
  624. SemIR::ConstType inst) const
  625. -> SemIR::CompleteTypeInfo {
  626. // The value representation of `const T` is the same as that of `T`.
  627. // Objects are not modifiable through their value representations.
  628. return GetNestedInfo(context_->types().GetTypeIdForTypeInstId(inst.inner_id));
  629. }
  630. auto TypeCompleter::BuildInfoForInst(SemIR::TypeId type_id,
  631. SemIR::CustomLayoutType /*inst*/) const
  632. -> SemIR::CompleteTypeInfo {
  633. // TODO: Should we support other value representations for custom layout
  634. // types?
  635. return {.value_repr = MakePointerValueRepr(type_id)};
  636. }
  637. auto TypeCompleter::BuildInfoForInst(SemIR::TypeId type_id,
  638. SemIR::MaybeUnformedType inst) const
  639. -> SemIR::CompleteTypeInfo {
  640. // `MaybeUnformed(T)` has the same value representation as `T` if that value
  641. // representation preserves all the bytes of the value, including any padding
  642. // bits. Otherwise we need to use a different representation.
  643. auto inner_type_id = context_->types().GetTypeIdForTypeInstId(inst.inner_id);
  644. auto nested = GetNestedInfo(inner_type_id);
  645. if (nested.value_repr.kind == SemIR::ValueRepr::Custom) {
  646. nested.value_repr = MakePointerValueRepr(type_id);
  647. } else if (nested.value_repr.kind == SemIR::ValueRepr::Copy) {
  648. auto type_inst = context_->types().GetAsInst(nested.value_repr.type_id);
  649. // TODO: Should ValueRepr::IsCopyOfObjectRepr return false for `bool`?
  650. if (!nested.value_repr.IsCopyOfObjectRepr(context_->sem_ir(),
  651. inner_type_id) ||
  652. type_inst.Is<SemIR::BoolType>()) {
  653. nested.value_repr = MakePointerValueRepr(type_id);
  654. }
  655. // TODO: Handle any other types that we treat as having discarded padding
  656. // bits. For now there are no such types, as all class types and all structs
  657. // and tuples with more than one element are passed indirectly.
  658. }
  659. return nested;
  660. }
  661. auto TypeCompleter::BuildInfoForInst(SemIR::TypeId /*type_id*/,
  662. SemIR::PartialType inst) const
  663. -> SemIR::CompleteTypeInfo {
  664. // The value representation of `partial T` is the same as that of `T`.
  665. // Objects are not modifiable through their value representations. However,
  666. // `partial T` is never abstract.
  667. return {
  668. .value_repr =
  669. GetNestedInfo(context_->types().GetTypeIdForTypeInstId(inst.inner_id))
  670. .value_repr,
  671. .abstract_class_id = SemIR::ClassId::None};
  672. }
  673. auto TypeCompleter::BuildInfoForInst(
  674. SemIR::TypeId /*type_id*/, SemIR::ImplWitnessAssociatedConstant inst) const
  675. -> SemIR::CompleteTypeInfo {
  676. return GetNestedInfo(inst.type_id);
  677. }
  678. // Builds and returns the value representation for the given type. All nested
  679. // types, as found by AddNestedIncompleteTypes, are known to be complete.
  680. auto TypeCompleter::BuildInfo(SemIR::TypeId type_id, SemIR::Inst inst) const
  681. -> SemIR::CompleteTypeInfo {
  682. // Use overload resolution to select the implementation, producing compile
  683. // errors when BuildInfoForInst isn't defined for a given instruction.
  684. CARBON_KIND_SWITCH(inst) {
  685. #define CARBON_SEM_IR_INST_KIND(Name) \
  686. case CARBON_KIND(SemIR::Name typed_inst): { \
  687. return BuildInfoForInst(type_id, typed_inst); \
  688. }
  689. #include "toolchain/sem_ir/inst_kind.def"
  690. }
  691. }
  692. auto TryToCompleteType(Context& context, SemIR::TypeId type_id,
  693. SemIR::LocId loc_id, bool diagnose) -> bool {
  694. return TypeCompleter(&context, loc_id, diagnose).Complete(type_id);
  695. }
  696. auto CompleteTypeOrCheckFail(Context& context, SemIR::TypeId type_id) -> void {
  697. bool complete =
  698. TypeCompleter(&context, SemIR::LocId::None, false).Complete(type_id);
  699. CARBON_CHECK(complete, "Expected {0} to be a complete type",
  700. context.types().GetAsInst(type_id));
  701. }
  702. auto RequireCompleteType(Context& context, SemIR::TypeId type_id,
  703. SemIR::LocId loc_id,
  704. DiagnosticContextFn diagnostic_context) -> bool {
  705. CARBON_CHECK(diagnostic_context);
  706. Diagnostics::ContextScope scope(&context.emitter(), diagnostic_context);
  707. if (!TypeCompleter(&context, loc_id, true).Complete(type_id)) {
  708. return false;
  709. }
  710. // For a symbolic type, create an instruction to require the corresponding
  711. // specific type to be complete.
  712. if (type_id.is_symbolic()) {
  713. // TODO: Deduplicate these.
  714. AddInstInNoBlock(
  715. context, loc_id,
  716. SemIR::RequireCompleteType{
  717. .type_id =
  718. GetSingletonType(context, SemIR::WitnessType::TypeInstId),
  719. .complete_type_inst_id = context.types().GetTypeInstId(type_id)});
  720. }
  721. return true;
  722. }
  723. auto TryIsConcreteType(Context& context, SemIR::TypeId type_id,
  724. SemIR::LocId loc_id) -> bool {
  725. if (!TryToCompleteType(context, type_id, loc_id)) {
  726. return false;
  727. }
  728. auto complete_info = context.types().GetCompleteTypeInfo(type_id);
  729. CARBON_CHECK(complete_info.value_repr.type_id.has_value(),
  730. "TryIsConcreteType called for an incomplete type. Call "
  731. "TryToCompleteType first.");
  732. return !complete_info.abstract_class_id.has_value();
  733. }
  734. auto RequireConcreteType(Context& context, SemIR::TypeId type_id,
  735. SemIR::LocId loc_id,
  736. DiagnosticContextFn complete_type_diagnostic_context,
  737. DiagnosticContextFn concrete_type_diagnostic_context)
  738. -> bool {
  739. if (!RequireCompleteType(context, type_id, loc_id,
  740. complete_type_diagnostic_context)) {
  741. return false;
  742. }
  743. CARBON_CHECK(concrete_type_diagnostic_context);
  744. Diagnostics::ContextScope scope(&context.emitter(),
  745. concrete_type_diagnostic_context);
  746. // TODO: For symbolic types, should add an implicit constraint that they are
  747. // not abstract.
  748. auto complete_info = context.types().GetCompleteTypeInfo(type_id);
  749. CARBON_CHECK(complete_info.value_repr.type_id.has_value(),
  750. "RequireConcreteType called for an incomplete type. Call "
  751. "RequireCompleteType first.");
  752. if (!complete_info.abstract_class_id.has_value()) {
  753. return true;
  754. }
  755. bool direct_use = false;
  756. if (auto inst = context.types().TryGetAs<SemIR::ClassType>(type_id)) {
  757. if (inst->class_id == complete_info.abstract_class_id) {
  758. direct_use = true;
  759. }
  760. }
  761. DiagnoseAbstractClass(context, complete_info.abstract_class_id, direct_use);
  762. return false;
  763. }
  764. // Given a canonical facet value, or a type value, return a facet value.
  765. static auto GetSelfFacetValue(Context& context, SemIR::ConstantId self_const_id)
  766. -> SemIR::ConstantId {
  767. if (self_const_id == SemIR::ErrorInst::ConstantId) {
  768. return SemIR::ErrorInst::ConstantId;
  769. }
  770. auto self_inst_id = context.constant_values().GetInstId(self_const_id);
  771. auto type_id = context.insts().Get(self_inst_id).type_id();
  772. CARBON_CHECK(context.types().IsFacetType(type_id));
  773. if (context.types().Is<SemIR::FacetType>(type_id)) {
  774. return self_const_id;
  775. }
  776. return GetConstantFacetValueForType(
  777. context, context.types().GetAsTypeInstId(self_inst_id));
  778. }
  779. static auto IdentifyFacetType(Context& context, SemIR::LocId loc_id,
  780. SemIR::ConstantId self_const_id,
  781. const SemIR::FacetType& facet_type,
  782. bool allow_partially_identified, bool diagnose)
  783. -> SemIR::IdentifiedFacetTypeId {
  784. // While partially identified facet types end up in the store of
  785. // IdentifiedFacetTypes, we don't try to construct a key to look for them
  786. // here, so we will only early-out here for fully identified facet types. To
  787. // construct the key for a partially identified facet type we need to know the
  788. // set of required impls that it contains, which requires us to do most of the
  789. // work of identifying the facet type (though we could skip the mapping of
  790. // constant values into specifics).
  791. auto key =
  792. SemIR::IdentifiedFacetTypeKey{.facet_type_id = facet_type.facet_type_id,
  793. .self_const_id = self_const_id};
  794. if (auto identified_id = context.identified_facet_types().Lookup(key);
  795. identified_id.has_value()) {
  796. return identified_id;
  797. }
  798. struct SelfImplsFacetType {
  799. bool extend;
  800. SemIR::ConstantId self;
  801. SemIR::FacetTypeId facet_type;
  802. };
  803. // Work queue.
  804. llvm::SmallVector<SelfImplsFacetType> work = {
  805. {true, self_const_id, facet_type.facet_type_id}};
  806. // Outputs for the IdentifiedFacetType.
  807. bool partially_identified = false;
  808. llvm::SmallVector<SemIR::IdentifiedFacetType::RequiredImpl> extends;
  809. llvm::SmallVector<SemIR::IdentifiedFacetType::RequiredImpl> impls;
  810. while (!work.empty()) {
  811. SelfImplsFacetType next_impls = work.pop_back_val();
  812. bool facet_type_extends = next_impls.extend;
  813. auto self_const_id = GetCanonicalFacetOrTypeValue(context, next_impls.self);
  814. const auto& facet_type_info =
  815. context.facet_types().Get(next_impls.facet_type);
  816. auto self_and_interface = [&](SemIR::SpecificInterface interface)
  817. -> SemIR::IdentifiedFacetType::RequiredImpl {
  818. return {self_const_id, interface};
  819. };
  820. if (facet_type_extends) {
  821. llvm::append_range(extends,
  822. llvm::map_range(facet_type_info.extend_constraints,
  823. self_and_interface));
  824. } else {
  825. llvm::append_range(impls,
  826. llvm::map_range(facet_type_info.extend_constraints,
  827. self_and_interface));
  828. }
  829. llvm::append_range(impls,
  830. llvm::map_range(facet_type_info.self_impls_constraints,
  831. self_and_interface));
  832. if (facet_type_info.extend_named_constraints.empty() &&
  833. facet_type_info.self_impls_named_constraints.empty()) {
  834. continue;
  835. }
  836. // The self may have type TypeType. But the `Self` in a generic require decl
  837. // has type FacetType, so we need something similar to replace it in the
  838. // specific.
  839. auto self_facet = GetSelfFacetValue(context, self_const_id);
  840. for (auto extends : facet_type_info.extend_named_constraints) {
  841. const auto& constraint =
  842. context.named_constraints().Get(extends.named_constraint_id);
  843. llvm::ArrayRef<SemIR::RequireImplsId> require_impls_ids;
  844. if (constraint.is_complete()) {
  845. require_impls_ids = context.require_impls_blocks().Get(
  846. constraint.require_impls_block_id);
  847. } else if (allow_partially_identified) {
  848. partially_identified = true;
  849. if (constraint.is_being_defined()) {
  850. require_impls_ids = context.require_impls_stack().PeekForScope(
  851. extends.named_constraint_id);
  852. } else {
  853. continue;
  854. }
  855. } else {
  856. if (diagnose) {
  857. DiagnoseIncompleteNamedConstraint(context,
  858. extends.named_constraint_id);
  859. }
  860. return SemIR::IdentifiedFacetTypeId::None;
  861. }
  862. auto constraint_with_self_specific_id = MakeSpecificWithInnerSelf(
  863. context, loc_id, constraint.generic_id,
  864. constraint.generic_with_self_id, extends.specific_id, self_facet);
  865. if (SpecificContainsError(context, constraint_with_self_specific_id)) {
  866. return SemIR::IdentifiedFacetTypeId::None;
  867. }
  868. for (auto require_impls_id : llvm::reverse(require_impls_ids)) {
  869. const auto& require = context.require_impls().Get(require_impls_id);
  870. // Each require is in its own generic, with no additional bindings and
  871. // no definition, so that they can have their specifics independently
  872. // instantiated.
  873. auto require_specific_id = CopySpecificToGeneric(
  874. context, SemIR::LocId(require.decl_id),
  875. constraint_with_self_specific_id, require.generic_id);
  876. auto require_self = GetConstantValueInSpecific(
  877. context.sem_ir(), require_specific_id, require.self_id);
  878. auto require_facet_type = GetConstantValueInSpecific(
  879. context.sem_ir(), require_specific_id, require.facet_type_inst_id);
  880. if (require_self == SemIR::ErrorInst::ConstantId ||
  881. require_facet_type == SemIR::ErrorInst::ConstantId) {
  882. return SemIR::IdentifiedFacetTypeId::None;
  883. }
  884. // TODO: Add and use constant_values().GetAs<SemIR::FacetType>().
  885. auto facet_type_inst_id =
  886. context.constant_values().GetInstId(require_facet_type);
  887. auto facet_type_id = context.insts()
  888. .GetAs<SemIR::FacetType>(facet_type_inst_id)
  889. .facet_type_id;
  890. bool extend = facet_type_extends && require.extend_self;
  891. work.push_back({extend, require_self, facet_type_id});
  892. }
  893. }
  894. for (auto impls : facet_type_info.self_impls_named_constraints) {
  895. const auto& constraint =
  896. context.named_constraints().Get(impls.named_constraint_id);
  897. llvm::ArrayRef<SemIR::RequireImplsId> require_impls_ids;
  898. if (constraint.is_complete()) {
  899. require_impls_ids = context.require_impls_blocks().Get(
  900. constraint.require_impls_block_id);
  901. } else if (allow_partially_identified) {
  902. partially_identified = true;
  903. if (constraint.is_being_defined()) {
  904. require_impls_ids = context.require_impls_stack().PeekForScope(
  905. impls.named_constraint_id);
  906. } else {
  907. continue;
  908. }
  909. } else {
  910. if (diagnose) {
  911. DiagnoseIncompleteNamedConstraint(context, impls.named_constraint_id);
  912. }
  913. return SemIR::IdentifiedFacetTypeId::None;
  914. }
  915. auto constraint_with_self_specific_id = MakeSpecificWithInnerSelf(
  916. context, loc_id, constraint.generic_id,
  917. constraint.generic_with_self_id, impls.specific_id, self_facet);
  918. if (SpecificContainsError(context, constraint_with_self_specific_id)) {
  919. return SemIR::IdentifiedFacetTypeId::None;
  920. }
  921. for (auto require_impls_id : llvm::reverse(require_impls_ids)) {
  922. const auto& require = context.require_impls().Get(require_impls_id);
  923. // Each require is in its own generic, with no additional bindings and
  924. // no definition, so that they can have their specifics independently
  925. // instantiated.
  926. auto require_specific_id = CopySpecificToGeneric(
  927. context, SemIR::LocId(require.decl_id),
  928. constraint_with_self_specific_id, require.generic_id);
  929. auto require_self = GetConstantValueInSpecific(
  930. context.sem_ir(), require_specific_id, require.self_id);
  931. auto require_facet_type = GetConstantValueInSpecific(
  932. context.sem_ir(), require_specific_id, require.facet_type_inst_id);
  933. if (require_self == SemIR::ErrorInst::ConstantId ||
  934. require_facet_type == SemIR::ErrorInst::ConstantId) {
  935. return SemIR::IdentifiedFacetTypeId::None;
  936. }
  937. // TODO: Add and use constant_values().GetAs<SemIR::FacetType>().
  938. auto facet_type_inst_id =
  939. context.constant_values().GetInstId(require_facet_type);
  940. auto facet_type_id = context.insts()
  941. .GetAs<SemIR::FacetType>(facet_type_inst_id)
  942. .facet_type_id;
  943. work.push_back({false, require_self, facet_type_id});
  944. }
  945. }
  946. }
  947. // TODO: Process other kinds of requirements.
  948. return context.identified_facet_types().Add(
  949. {key, partially_identified, extends, impls});
  950. }
  951. auto TryToIdentifyFacetType(Context& context, SemIR::LocId loc_id,
  952. SemIR::ConstantId self_const_id,
  953. const SemIR::FacetType& facet_type,
  954. bool allow_partially_identified)
  955. -> SemIR::IdentifiedFacetTypeId {
  956. return IdentifyFacetType(context, loc_id, self_const_id, facet_type,
  957. allow_partially_identified, /*diagnose=*/false);
  958. }
  959. auto RequireIdentifiedFacetType(Context& context, SemIR::LocId loc_id,
  960. SemIR::ConstantId self_const_id,
  961. const SemIR::FacetType& facet_type,
  962. DiagnosticContextFn diagnostic_context,
  963. bool diagnose) -> SemIR::IdentifiedFacetTypeId {
  964. CARBON_CHECK(diagnostic_context);
  965. Diagnostics::ContextScope scope(&context.emitter(), diagnostic_context);
  966. return IdentifyFacetType(context, loc_id, self_const_id, facet_type,
  967. /*allow_partially_identified=*/false, diagnose);
  968. }
  969. } // namespace Carbon::Check