type_completion.cpp 43 KB

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